Maximum sum
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 37961 | Accepted: 11859 |
Description
Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:
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.
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.
Huge input,scanf is recommended.
Source
POJ Contest,Author:Mathematica@ZSU
题意:给一个子序列,求出数列中不相交的两个字段和,要求和最大。
从两个方向来讨论,前和后,求出来到每一个点对应的最大的数列的和,然后for循环寻找就可以了
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <vector>
#include <map>
#include <set>
#define M(n,m) memset(n,m,sizeof(n));
const int MAX = 0x3f3f3f3f;
const int MIN = -1<<28;
const int INF = 0x3f3f3f3f;
using namespace std;
int a[50010];
int l[50010];
int r[50010];
int main()
{
int n,t;
scanf("%d",&t);
while(t --)
{
///初始化
M(a,0)
M(l,0)
M(r,0)
scanf("%d",&n);
for(int i = 0; i < n; i ++)
scanf("%d",&a[i]);
///l数组用来求从左边向右更新的最大值
l[0] = a[0];
for(int i = 1; i < n; i ++)
if(l[i - 1] < 0)
l[i] = a[i];
else
l[i] = l[i - 1] + a[i];
for(int i = 1; i < n; i ++)
if(l[i] < l[i - 1]) ///对left的值用它前面的项进行更新
l[i] = l[i - 1];
///方法思想都同l数组
r[n - 1] = a[n - 1];
for(int i = n - 2; i >= 0; i --)
if(r[i + 1] < 0)
r[i] = a[i];
else
r[i] = a[i] + r[i + 1];
for(int i = n - 2; i >= 0; i --)
if(r[i] < r[i + 1])
r[i] = r[i + 1];
///寻找对应的最大值
int ans = MIN;
for(int i = 1; i < n; i ++)
{
if(ans < l[i - 1] + r[i])
ans = l[i - 1] + r[i];
}
printf("%d\n",ans);
}
return 0;
}