Max Sum Plus Plus
题目描述
求m个不相交子段和最大值
题解
首先明白每个元素的状态。要么加入前一个块,要么自己成一个组。
s[i][j]表示前j个元素分成i组的最大值,则转移方程为:
s[i][j]=max(s[i][j-1]+a[j],max(s[i-1][k]+a[j]));其中k大于等于i-1并且<j
发现n=1000000,m未知,m稍大会报内存。
考虑优化,发现当当前元素独立成一组i时,我们只需要在它前面第i-1组中取一个最大的
就可以,这个操作我们可以边处理边记录前面的MAX,我们还可以用dp[j]表示第j个元素加入
所选的最大值。
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define INF 0x7fffffff int n,m,ansmax; int a[1000009],dp[1000009],premax[1000009]; int main(){ while(scanf("%d%d",&m,&n)!=EOF){ memset(dp,0,sizeof(dp)); memset(premax,0,sizeof(premax)); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=m;i++){ ansmax=-INF; for(int j=i;j<=n;j++){ dp[j]=max(dp[j-1]+a[j],premax[j-1]+a[j]); premax[j-1]=ansmax; ansmax=max(ansmax,dp[j]); } } printf("%d ",ansmax); } return 0; }