Max Sum Plus Plus
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1024
解题思路:
给你一个数组,求其分成m个不相交子段和最大值的问题。
设a为给定数组,n为数组中的元素总数,dp[i][j]表示前i个数在选取第i个数的前提下分成j段的最大值,其中1<=j<=i<=n && j<=m,则
状态转移方程为:
dp[i][j] = max(dp[i][j-1],max(dp[i-1][k]))+a[j](i-1<=k<=j-1)
由于n的范围太大,
用滚动数组来优化空间;
用pre[](前一轮的最大值)来优化时间。
AC代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1000005;
int a[maxn],dp[maxn],pre[maxn];
int main(){
int m,n,ans;
while(~scanf("%d%d",&m,&n)){
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
dp[0] = 0;
memset(pre,0,sizeof(pre));
for(int i = 1; i <= m; i++){
ans = -INF;
for(int j = i; j <= n; j++){
dp[j] = max(dp[j-1],pre[j-1])+a[j];
pre[j-1] = ans;
ans = max(ans,dp[j]);
}
}
printf("%d\n",ans);
}
return 0;
}