Maximum sum
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 38079 | Accepted: 11904 |
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.
题目大意:将区间分成了两部分,让你求这两部分的和最大是多少。
思路分析:前面做过求最大连续序列和的题目,是用dp做的,状态转移方程为dp[i]=max[dp[i-1]+a[i],a[i])
这道题与那道题很像,唯一的区别就是区间变成了两部分,现在要求和最大,dp[i]的意思是以i结尾的子串的最大
和,现在可以把分成求两个dp,l[i]代表i之前的最大和,r[i]代表i之后的最大和,题目要求的不就是求l[i-1]+r[i]的
最大值么,现在问题就变成了如何求了l[i]和r[i],状态转移方程很容易确定,l[i]=max(l[i-1],t1[i]),t1[i]指的是
以i个数结尾的最大子串和,这样问题经过几步分解就变成了已经解决过的问题了。
以i个数结尾的最大子串和,这样问题经过几步分解就变成了已经解决过的问题了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int maxn=50000+100;
int a[maxn],t1[maxn],t2[maxn],l[maxn],r[maxn];
const int inf=-1000001;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(t1,0,sizeof(t1));
memset(t2,0,sizeof(t2));
for(int i=1;i<=n;i++)
{
t1[i]=max(t1[i-1]+a[i],a[i]);
}
for(int i=n;i>=1;i--)
{
t2[i]=max(t2[i+1]+a[i],a[i]);
}
l[1]=a[1];
for(int i=2;i<=n;i++)
{
l[i]=max(l[i-1],t1[i]);
}
r[n]=a[n];
for(int i=n-1;i>=1;i--)
{
r[i]=max(r[i+1],t2[i]);
}
int ma=inf;
for(int i=2;i<=n;i++)
{
int t=l[i-1]+r[i];
ma=max(ma,t);
}
cout<<ma<<endl;
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int maxn=50000+100;
int a[maxn],t1[maxn],t2[maxn],l[maxn],r[maxn];
const int inf=-1000001;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(t1,0,sizeof(t1));
memset(t2,0,sizeof(t2));
for(int i=1;i<=n;i++)
{
t1[i]=max(t1[i-1]+a[i],a[i]);
}
for(int i=n;i>=1;i--)
{
t2[i]=max(t2[i+1]+a[i],a[i]);
}
l[1]=a[1];
for(int i=2;i<=n;i++)
{
l[i]=max(l[i-1],t1[i]);
}
r[n]=a[n];
for(int i=n-1;i>=1;i--)
{
r[i]=max(r[i+1],t2[i]);
}
int ma=inf;
for(int i=2;i<=n;i++)
{
int t=l[i-1]+r[i];
ma=max(ma,t);
}
cout<<ma<<endl;
}
return 0;
}