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 }

 

posted @ 2015-10-30 15:18  CXCXCXC  阅读(190)  评论(0编辑  收藏  举报