HDU 1024 Max Sum Plus Plus(二维数组转化为一维数组)

Problem Description:
Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^
 
Input:
Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
Process to the end of file.
 
Output:
Output the maximal summation described above in one line.
 
Sample Input:
1 3 1 2 3
2 6 -1 4 -2 3 -2 3
 
Sample Output:
6
8
 
Hint
Huge input, scanf and dynamic programming is recommended.
 
题意:有一个长度为n的序列,现在要被分成不交叉的m段序列(不用分完所有的元素),问怎样分才能使这m段序列的和最大,这道题不求这m段是什么,只用输出这个最大的值。
 
假设我们让数组a[j]表示输入的数组,DP[i][j]表示前j个数被分成i组的最大和(不用分完所有前j个元素),那么我们必须明白:第j个数可能被独立分成第i组,也可能加在第j-1个数的后面,成为第i组的元素(此时第i组元素只有第j个数),所以状态转移方程变为dp[j] = max(dp[j-1]+a[j], Max[j-1]+a[j])   (因为如果开二维数组内存过大,所以我们可以采用双重for循环形式进行计算最大值,此时只需要两个一维数组就可以了)。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

const int N=1000010;
const int INF=0x3f3f3f3f;

int a[N], dp[N], Max[N]; ///dp[j]存放前j个数分组后的最大值,Max[j-1]存放上一组的最大值

int main ()
{
    int m, n, i, j, M;

    while (scanf("%d%d", &m, &n) != EOF)
    {
        for (i = 1; i <= n; i++)
            scanf("%d", &a[i]);

        memset(dp, 0, sizeof(dp));
        memset(Max, 0, sizeof(Max));

        for (i = 1; i <= m; i++) ///i代表组数,j代表元素个数
        {
            M = -INF; ///每次多分一组都需要统计最大值

            for (j = i; j <= n; j++) ///j从i开始是因为组数肯定要比元素个数少
            {
                dp[j] = max(dp[j-1]+a[j], Max[j-1]+a[j]); ///dp[j-1]+a[j]代表a[j]连在a[j-1]后面成为第i组,但是该组只有a[j]一个元素,Max[j-1]+a[j]代表a[j]独立成组
                Max[j-1] = M; ///先保存最大值,后计算这一组的最大值,则下次使用Max数组时就变成了上一组的最大值了
                M = max(M, dp[j]);
            }
        }

        printf("%d
", M);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/syhandll/p/4784209.html