HDU 1024 Max Sum Plus Plus
题意
求一段序列的m个子段的最大和
思路
1.DP
2.对于每一个数,分类讨论它是属于前一个子段或者是单独成段。
3.状态转移方程
dp[i][j]=以j结尾的有i段子段的最大和
dp[i][j]=Max(dp[i][j-1]+a[j] , Max( dp[i-1][k] ) + a[j] ) 0<k<j
但是这么搞会TLE,所以要优化到O(n^2)。
记pre[j]=(i-1)个子段时dp[i-1][k](k:1)的最大值,为下次计算所用。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000000+100;
const int inf=0x3f3f3f3f;
int a[maxn],f[maxn],pre[maxn];
int main(){
// freopen("AAA.in","r",stdin);
int n,m;
while(~scanf("%d%d",&m,&n)){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
f[i]=pre[i]=0;
}
int mx;
for(int i=1;i<=m;i++){
mx=-inf;
for(int j=i;j<=n;j++){
f[j]=max(f[j-1]+a[j],pre[j-1]+a[j]);
pre[j-1]=mx;
mx=max(mx,f[j]);
}
}
printf("%d
",mx);
}
return 0;
}
后记
用pre优化时间的时候,发现空间也可以顺便优化了。