zoukankan      html  css  js  c++  java
  • Max Sum Plus Plus

    A - Max Sum Plus Plus
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    Submit Status

    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 S 1, S 2, S 3, S 4 ... S x, ... S n (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ S x ≤ 32767). We define a function sum(i, j) = S i + ... + S j (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(i 1, j 1) + sum(i 2, j 2) + sum(i 3, j 3) + ... + sum(i m, j m) maximal (i x ≤ i y ≤ j x or i x ≤ j y ≤ j x 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(i x, j x)(1 ≤ x ≤ m) instead. ^_^ 
     

    Input

    Each test case will begin with two integers m and n, followed by n integers S 1, S 2, S 3 ... S n
    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字段和,dp数组,dp[i][j]表示以a[j]结尾的,i个字段的最大和
    
        两种情况:1.第a[j]元素单独作为第i个字段
                2.第a[j]元素和前面的字段共同当做第i个字段
    
        得到状态转移方程:dp[i][j]=max( dp[i][j-1]+a[j] , max(dp[i-1][t])+a[j]);
        
        但是实际情况是,时间复杂度和空间复杂度都是相当的高,所以要进行时间和空间的优化:
            将每次遍历的时候的max(dp[i-1][t]) 用一个数组d储存起来,这样就能省去寻找max(dp[i-1][t])的时间,
            这样状态转移方程就变成了 dp[i][j]=max( dp[i][j-1]+a[j] , d[j-1]+a[j]), 会发现dp数组的可以
            省去一维,因为每次都是和前一次的状态有关,所以可以记录前一次状态,再用一个变量tmp记录下dp[i][j-1],
            这样方程就变成了 dp[i][j]=max( tmp+a[j] , d[j-1]+a[j]);这样就可以化简一下就是:dp[i][j]=
            max( tmp , d[j-1])+a[j];
            
    */
    #include <bits/stdc++.h>
    #define N 1000005
    using namespace std;
    int a[N];
    int n,m;
    int d[N];//用来存储j-1的位置用来存储 max(dp[i-1][t])
    int main(){
        // freopen("in.txt","r",stdin);
        while(scanf("%d%d",&m,&n)!=EOF){
            memset(d,0,sizeof d);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            /*
                dp[i][j]=max( dp[i][j-1]+a[j] , max(dp[i-1][t])+a[j])
            */
            for(int i=1;i<=m;i++){//遍历字段
                int tmp = 0;//用来记录dp[i-1][j]
                for(int k = 1; k <= i; ++k)
                    tmp += a[k];
                //由于d[n]的位置是永远都用不到的,所以就用来存储最后的姐
                d[n] = tmp;//前面的i项,每项都是一个段的时候
                
                for(int j = i+1; j <= n; ++j)
                {
                    tmp = max(d[j-1], tmp) + a[j]; //a[j]单独作为一个段的情况 和 前面的max(dp[i-1][t])
    
                    d[j-1] = d[n];//将这个值保存下来
    
                    d[n] = max(d[n], tmp); //比较大小方便答案的输出
                }
            }
            printf("%d
    ",d[n]);
        }
        return 0;
    }
  • 相关阅读:
    HDU 5059 Help him
    HDU 5058 So easy
    HDU 5056 Boring count
    HDU 5055 Bob and math problem
    HDU 5054 Alice and Bob
    HDU 5019 Revenge of GCD
    HDU 5018 Revenge of Fibonacci
    HDU 1556 Color the ball
    CodeForces 702D Road to Post Office
    CodeForces 702C Cellular Network
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6546901.html
Copyright © 2011-2022 走看看