题目大意:给定一个序列,让求该序列的m段互不重叠的子序列和的最大和;可以说是POJ2479的升级版了。
我们可以用一个二维数组dp(i,j)来表示该序列由前j个元素中的i个互不重叠的子序列和的最大和,
dp(i,j)=max(dp(i,j-1),max(dp(i-1,k)))+ans(j),其中k=1,2,3......j-1;
其实max(dp(i,k))就是前一个状态的dp()的最大值,我们可以在计算的时候就直接纪录下来,这样时间复杂度就由O(n^3)降到了O(n^2)
代码如下:
#include <cstdio> #include <cstring> #include <iostream> #define MAX 1000010 #define INF -999999999 using namespace std; int a[MAX],dp[MAX],temp[MAX]; int main() { int m,n,i,j; int nmin,ans; while(cin>>m>>n) { memset(dp,0,sizeof(dp)); memset(temp,0,sizeof(temp)); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=m;i++) { nmin=ans=INF; for(j=i;j<=n;j++) { dp[j]=max(dp[j-1],temp[j-1])+a[j]; temp[j-1]=ans; ans=max(ans,dp[j]); } } printf("%d\n",ans); } return 0; }