1 https://vjudge.net/contest/68966#problem/A 2 3 http://www.cnblogs.com/kuangbin/archive/2011/08/04/2127085.html 4 5 /* 6 状态dp[i][j]有前j个数,组成i组的和的最大值。决策: 7 第j个数,是在第包含在第i组里面,还是自己独立成组。 8 方程 dp[i][j]=Max(dp[i][j-1]+a[j] , max( dp[i-1][k] ) + a[j] ) 0<k<j 9 空间复杂度,m未知,n<=1000000, 继续滚动数组。 10 时间复杂度 n^3. n<=1000000. 显然会超时,继续优化。 11 max( dp[i-1][k] ) 就是上一组 0....j-1 的最大值。 12 我们可以在每次计算dp[i][j]的时候记录下前j个的最大值 13 用数组保存下来 下次计算的时候可以用,这样时间复杂度为 n^2. 14 */ 15 16 #include<stdio.h> 17 #include<algorithm> 18 #include<iostream> 19 using namespace std; 20 #define MAXN 1000000 21 #define INF 0x7fffffff 22 int dp[MAXN+10]; 23 int mmax[MAXN+10]; 24 int a[MAXN+10]; 25 int main() 26 { 27 int n,m; 28 int i,j,mmmax; 29 while(scanf("%d%d",&m,&n)!=EOF) 30 { 31 for(i=1;i<=n;i++) 32 { 33 scanf("%d",&a[i]); 34 mmax[i]=0; 35 dp[i]=0; 36 } 37 dp[0]=0; 38 mmax[0]=0; 39 for(i=1;i<=m;i++) 40 { 41 mmmax=-INF; 42 for(j=i;j<=n;j++) 43 { 44 //第j个数一定在某个组中,否则的话和dp[0~j-1]有重复(dp[4]的a[4]不在这个组和dp[3]可能是一样的) 45 //两种情况:1.a[j]前面已经有i个组,加上a[j]还是4个组,只有一种可能,a[j]是合并到dp[j-1]中的 46 // 2.a[j]前面有i-1个组,那么a[j]就是一个独立的组(也可以和a[j-1]紧挨,这是a[j]也独立),找出i-1个组 // dp[1~j-1]中最大的。 47 dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]); 48 printf("dp[%d]=%d ",j,dp[j]); 49 //这是一个滚动数组,每次上面“dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]);”中的mmax[j-1]是i-1组中的最大值, //用完之后就更新成为i组的最大值。mmax[i-1]以后再也不用,更新为-INF。mmax[j-1]每次都更新为i组中dp //[i~j-1]的最大值 50 mmax[j-1]=mmmax; 51 printf("mmax[%d]=%d ",j-1,mmmax); 52 mmmax=max(mmmax,dp[j]); 53 } 54 } 55 printf("%d ",mmmax); 56 57 } 58 return 0; 59 }