由于数据很大,利用滚动数组。
状态转移方程 dp[1][j]=max(dp[0][j-1]+a[j], dp[1][j-1]+a[j]);
dp[0][j-1]表示a[1]到a[j-1]的i-1个子段的最大值,不一定包含a[j-1]。
dp[1][j-1]表示a[1]到a[j-1]的i个子段的最大值,一定包含a[j-1]。
dp[1][i]表示a[1]到a[j]的i个子段的最大值,一定包含a[j]。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1000005;
int dp[2][maxn], a[maxn], n, m;
int max(int x, int y){
return x>y?x:y;
}
int main(){
//freopen("1.txt", "r", stdin);
int i, j, tmp;
while(scanf("%d%d", &m, &n)!=EOF){
for(i=1; i<=n; i++)
scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
for(i=1; i<=m; i++){
tmp=-0x7fffffff;
for(j=i; j<=n; j++){
dp[1][j]=max(dp[0][j-1]+a[j], dp[1][j-1]+a[j]);
dp[0][j-1]=tmp;//更新dp[0][j-1]为a[1]到a[j-1]不一定包含a[j-1]的i个子段的最大值。(原来是i-1个子段)
if(dp[1][j]>tmp)
tmp=dp[1][j];//更新tmp的值,tmp为a[1]到a[j]不一定包含a[j]的i个子段的最大值。
}
}
printf("%d\n", tmp);
}
return 0;
}