思路:利用動態規劃的方法,求解最大m子段的和,由於這一題的數據量很大,所以不能用二維的dp 方 程,考慮優化
用一個temp[1000005]來存儲前j個元素的i個子段的最大和,則有dp[j]=max(dp[j-1]+s[j],temp[j-1]]+s[j]) 表示以s[j]結尾的元素的最大的子段和
注意:輸入數據很多使用scanf
代碼:
#include <iostream>
#include <algorithm>
#include <map>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int s[1000005];
int dp[1000005];
int temp[1000005];
void DP(int m , int n){
int i , j , k;
int max;
memset(dp , 0 ,sizeof(dp));
memset(temp , 0 , sizeof(temp));
for(i = 1 ; i <= m ; i++){//用以個for循環遍歷
max = -999999999;//注意這裡的max要為無窮小,分別在求i子段最大和時候進行初始化
for(j = i ; j <= n ; j++){
dp[j] = (dp[j-1] + s[j]) > (temp[j-1] + s[j])?(dp[j-1] + s[j]) : (temp[j-1] + s[j]);
temp[j-1] = max;//這裡的temp[j-1]用來存儲前面j-1的元素i子段最大值,注意不是temp[j]因為還沒判 斷是否max<dp[j];
if(max < dp[j])
max = dp[j];//更新max
}
}
cout<<max<<endl;
}
int main(){
int i , j;
int n , m;
while(scanf("%d%d" , &m , &n) != EOF){
for(i = 1 ; i <= n ; i++)
scanf("%d" , &s[i]);
DP(m , n);
}
return 0;
}
作者:cgl1079743846