【noiOJ】p1481
1481:Maximum sum
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
- 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). - 输入
- 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. - 输出
- Print exactly one line for each test case. The line should contain the integer d(A).
- 样例输入
-
1 10 1 -1 2 2 3 -3 4 -4 5 -5
- 样例输出
-
13
- 提示
- In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer.
Huge input,scanf is recommended. - 来源
- POJ Contest,Author:Mathematica@ZSU
- source:最大双子序列和,枚举i,分别统计i左边最大子序列和右边最大子序列。(改变一下代码风格)
-
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <cstring> 5 using namespace std; 6 int n,datanum,maxn; 7 int a[50000+10],leftmax[50000+10],rightmax[50000+10]; 8 int main() 9 { 10 int w,i; 11 scanf("%d",&datanum); 12 for (w=1;w<=datanum;w++) 13 { 14 memset(a,0,sizeof(0)); 15 memset(leftmax,0,sizeof(leftmax)); 16 memset(rightmax,0,sizeof(rightmax)); 17 scanf("%d",&n); 18 for (i=1;i<=n;i++) 19 scanf("%d",&a[i]); 20 leftmax[1]=a[1]; 21 for (i=2;i<=n;i++) 22 if (leftmax[i-1]>0) leftmax[i]=leftmax[i-1]+a[i]; 23 else leftmax[i]=a[i]; 24 for (i=2;i<=n;i++) 25 if (leftmax[i]<leftmax[i-1]) leftmax[i]=leftmax[i-1]; 26 rightmax[n]=a[n]; 27 for (i=n-1;i>=1;i--) 28 if (rightmax[i+1]>0) rightmax[i]=rightmax[i+1]+a[i]; 29 else rightmax[i]=a[i]; 30 for (i=n-1;i>=1;i--) 31 if (rightmax[i]<rightmax[i+1]) 32 rightmax[i]=rightmax[i+1]; 33 maxn=-99999999; 34 for (i=1;i<n;i++) 35 maxn=max(maxn,leftmax[i]+rightmax[i+1]); 36 printf("%d\n",maxn); 37 } 38 return 0; 39 }
—Anime Otaku Save The World.