標題:乘積最大
給定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; }
