Maximum sum
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. 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
|
题意:
给你n个数字的序列。叫你找出两个连续子段。两子段不重合。使得两字段中所有数字的和最大。
思路:
开始因为没注意到不重合WA了数次!解法还是蛮简单的。从前往后和从后往前分别做一次最大子段和。然后枚举分段点。就可以得到答案了。
详细见代码:
#include<algorithm>
#include<iostream>
#include<string.h>
#include<sstream>
#include<stdio.h>
#include<math.h>
#include<vector>
#include<string>
#include<queue>
#include<set>
#include<map>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
const double PI=acos(-1.0);
const int maxn=50100;
int dpl[maxn],dpr[maxn],ml[maxn],arr[maxn];
int main()
{
int t,n,i,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ans=-INF;
dpl[0]=dpr[n+1]=ml[0]=0;
for(i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
dpl[i]=max(arr[i],arr[i]+dpl[i-1]);//从前往后
ans=max(ans,dpl[i]);
ml[i]=ans;//记录到i时的最大字段和
}
ans=-INF;//必须要再次初始化。开始偷懒认为死一样的。结果会导致最后只有一个字段。数据见下
for(i=n;i>1;i--)
{
dpr[i]=max(arr[i],arr[i]+dpr[i+1]);
ans=max(ans,ml[i-1]+dpr[i]);
}
printf("%d\n",ans);
}
return 0;
}
/*
1
10
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*/