题意:从数列中选出m段不相交的连续子段,求这个和最大。
wa了一个晚上,不爽,最后拿人家的程序对拍才发现问题。
这题要有优化,要记录上层的最优解,这里有点不好处理。
状态:dp[i][j]表示以j结尾的i个子段和的最优解;
转移:dp[i][j] = max{dp[i][j-1],max{dp[i-1][t]}}+a[j];
用了滚动数组,还有记录上层最优,等优化时间,空间;
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
4729397 | 2011-10-09 22:35:38 | Accepted | 1024 | 500MS | 1440K | 658 B | C++ | xym2010 |
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1000005;
int n,m,a[maxn],dp[maxn],c[maxn];
void DP()
{
int tem=0,ans=-(1<<31);
for(int i=0;i<=n;i++)
dp[i]=c[i]=0;
for(int i=1;i<=m;i++)
{
for(int j=i;j<=n;j++)
{
dp[j]=max(dp[j-1],tem)+a[j-1];
tem=c[j];
c[j]=i==j?dp[j]:max(c[j-1],dp[j]);
}
tem=c[i];
}
for(int i=m;i<=n;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
DP();
}
return 0;
}