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\n",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\n",j-1,mmmax);
52 mmmax=max(mmmax,dp[j]);
53 }
54 }
55 printf("%d\n",mmmax);
56
57 }
58 return 0;
59 }