第九屆藍橋杯第十個題(乘積最大)題解



標題:乘積最大

給定N個整數A1, A2, ... AN。請你從中選出K個數,使其乘積最大。

請你求出最大的乘積,由於乘積可能超出整型范圍,你只需輸出乘積除以1000000009的余數。

注意,如果X<0, 我們定義X除以1000000009的余數是負(-X)除以1000000009的余數。
即:0-((0-x) % 1000000009)

【輸入格式】
第一行包含兩個整數N和K。
以下N行每行一個整數Ai。

對於40%的數據,1 <= K <= N <= 100
對於60%的數據,1 <= K <= 1000
對於100%的數據,1 <= K <= N <= 100000 -100000 <= Ai <= 100000

【輸出格式】
一個整數,表示答案。


【輸入樣例】
5 3
-100000
-10000
2
100000
10000

【輸出樣例】
999100009

再例如:
【輸入樣例】
5 3
-100000
-100000
-2
-100000
-100000

【輸出樣例】
-999999829


資源約定:
峰值內存消耗(含虛擬機) < 256M
CPU消耗 < 1000ms


請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。

注意:
main函數需要返回0;
只使用ANSI C/ANSI C++ 標准;
不要調用依賴於編譯環境或操作系統的特殊函數。
所有依賴的函數必須明確地在源文件中 #include <xxx>
不能通過工程設置而省略常用頭文件。

提交程序時,注意選擇所期望的語言類型和編譯器類型。

 

思路:比賽的時候不會DP寫法,就是針對實例寫了下,騙了點分。

先將數據保存到數組a,然后找出K個數使其乘積最大的大問題分解成為找出K-1個數乘積最大、K-2個數最大、k-3個數最大.......直到找出一個數最大的情況。

兄弟要是最不出一個數最大的話,下面不易觀看。然后在我們將大問題分解成小問題之后,我們要將這些小問題之間的關系用數學式子清楚的表達出來。

對於每個小問題的最佳狀態我們用dp[][]來存放。最后寫的時候注意在數組上要進行優化,用INT數組來存我這里會出錯,所以我用了long long,因為每一個判斷其實只需要上一次的最佳決解狀態就行,所以也循環利用了數組進行了優化。時間復雜度O(n*k)

  • 數學式子:

 

  • 第一個樣例:

 

 自己寫的疑似AC代碼:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
long long a[100005], dp[2][100005];
int main() 
{
    int n, k;
    cin >> n >> k;
    for (int i = 0; i < n; i++){
        cin >> a[i];
    }
    for (int i = 0; i < k; i++){

        int s = (i - 1) % 2, t = i % 2;

        if (i == 0){
            for (int j = i; j < n;j++)
            if (j == 0){
                dp[0][j] = a[j];
            }
            else {
                if (dp[0][j - 1] > a[j])
                    dp[0][j] = dp[0][j - 1];
                else dp[0][j] = a[j];
            }
        }
        else {
            for (int j = i; j < n; j++){
                if (i == j)dp[t][j] = (dp[s][j - 1] * a[j]) % 1000000009;
                else {
                    if (dp[t][j - 1]>a[j] * dp[s][j - 1])
                        dp[t][j] = dp[t][j - 1];
                    else dp[t][j] = (a[j] * dp[s][j - 1]) % 1000000009;
                }
            }    
        }
    }

    cout << dp[(k - 1) % 2][n - 1] << endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM