zoukankan      html  css  js  c++  java
  • Maximum sum

    Time Limit: 
    1000ms
     
    Memory Limit: 
    65536kB
    Description
    Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:
                         t1     t2 
    d(A) = max{ ∑ai + ∑aj | 1 <= s1 <= t1 < s2 <= t2 <= n }
    i=s1 j=s2

    Your task is to calculate d(A).
    Input
    The input consists of T(<=30) test cases. The number of test cases (T) is given in the first line of the input. 
    Each test case contains two lines. The first line is an integer n(2<=n<=50000). The second line contains n integers: a1, a2, ..., an. (|ai| <= 10000).There is an empty line after each case.
    Output
    Print exactly one line for each test case. The line should contain the integer d(A).
    Sample Input
    1
    
    10
    1 -1 2 2 3 -3 4 -4 5 -5
    Sample Output
    13
    Hint
    In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer.

    Huge input,scanf is recommended.
    Source
      POJ Contest,Author:Mathematica@ZSU
    题意:给定T个序列,对于每个序列,从中找出两个不重叠的子序列,使得加和起来最大。
    思路:
      维护两个数组lsum[],rsum[],lsum[i]表示i及i以前的最长连续序列和(一定包含i),rsum[j]表示j及j以后的最长连续序列和(一定包含j),则答案非常容易推出:ANS=max(ANS,lsum[i]+rsum[j] | 1<=i<=N,i+1<=j<=N),这样就可以两重循环,枚举i和j。
      但是由于N(即序列长度)非常大,达到50000,所以任何N^2的算法都会超时,因此这题就要O(n)去解决,所以要对lsum和rsum进行改造,现在令lsum[i]表示i及i以前的最长连续序列和(不一定包含i),rsum[j]表示j及j以后的最长连续序列和(不一定包含j),则答案为ANS=max(ANS,lsum[i]+rsum[i+1] | 1<=i<=N)。这时求出lsum[],rsum[],就比较麻烦了,以lsum[i]为例,首先用f[i]来计算一定包含i的lsum,则真正的lsum[]就是max(f[i],lsum[i-1]),代码如下:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int inf=-1e9;
     4 int T,N;
     5 int a[50005];
     6 int lsum[50005];
     7 int rsum[500005];
     8 int f[50005];
     9 int ANS=inf;
    10 int main(){
    11     scanf("%d",&T);
    12     for(int z=1;z<=T;z++){
    13         ANS=inf;
    14         memset(a,0,sizeof(a));
    15         memset(lsum,0,sizeof(lsum));
    16         memset(rsum,0,sizeof(rsum));
    17         memset(f,0,sizeof(f));
    18         scanf("%d",&N);
    19         for(int i=1;i<=N;i++) scanf("%d",&a[i]);
    20         f[0]=inf; lsum[0]=inf;
    21         f[N+1]=inf; rsum[N+1]=inf;
    22         for(int i=1;i<=N;i++){
    23             f[i]=max(a[i],f[i-1]+a[i]);
    24             lsum[i]=max(f[i],lsum[i-1]);
    25         }
    26         memset(f,0,sizeof(f));
    27         for(int i=N;i>=1;i--){
    28             f[i]=max(a[i],f[i+1]+a[i]);
    29             rsum[i]=max(f[i],rsum[i+1]);
    30         }
    31         for(int i=1;i<=N;i++){
    32             ANS=max(ANS,lsum[i]+rsum[i+1]);
    33         }
    34         cout<<ANS<<endl;
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    LeetCode OJ-- Spiral Matrix II
    LeetCode OJ-- Reverse Integer
    LeetCode OJ-- Spiral Matrix
    LeetCode OJ-- Trapping Rain Water*
    LeetCode OJ--Triangle **
    LeetCode OJ-- Sqrt(x) *
    LeetCode OJ-- Simplify Path **
    lol人物模型提取(一)
    3ds Max学习日记(九)
    YaoLingJump开发者日志(八)V1.1版本完成
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/4923367.html
Copyright © 2011-2022 走看看