• 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;
    }
  • 相关阅读:
    VS2010安装笔记
    Blend4中文版中截取图片的方法
    改变窗口的位置 (转载)
    窗口的位置
    windows消息大全
    WM_MOUSELEAVE和WM_MOUSEHOVER使用
    setwindowpos
    无注册表的COM调用
    WM_CLOSE WM_QUIT WM_DESTROY 三者的区别
    WM_MOUSEWHEEL消息
  • 原文地址:https://www.cnblogs.com/syhandll/p/4784209.html
Copyright © 2020-2023  润新知