题意:
给出几组整数序列,找2个不重合的连续子序列使它们的和最大。
思路:
设kt[i]为以第i个数开头的连续子序列的最大值,wb[i]为以第i个数结尾的最大值,可得wb[i]=max(0,s[i]-x),kt[i]=max(kt[i+1],s[i]-x),再把kt[i]+wb[i+1]加起来求最大值。
代码:
#include<cstdio>
#include<cstring>
int ans,x,t,n,a[50001],s[50001],kt[50001],wb[50001];
int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int main()
{
scanf("%d",&t);
while (t--)
{
memset(kt,0,sizeof(kt));
memset(wb,0,sizeof(wb));
memset(s,0,sizeof(s));
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s[i]=s[i-1]+a[i];//求前缀和,用来求wb
}
wb[1]=s[1];x=min(s[1],0);
for (int i=2;i<=n;i++)
{
wb[i]=max(0,s[i]-x);
x=min(x,s[i]);
}
for (int i=n;i>=1;i--)
s[i]=s[i+1]+a[i];//求后缀和,用来求kt
kt[n]=a[n];x=min(s[n],0);
for (int i=n-1;i>=1;i--)
{
kt[i]=max(s[i]-x,kt[i+1]);
x=min(x,s[i]);
}
ans=-2100000000;
for (int i=1;i<=n;i++)
ans=max(ans,wb[i]+kt[i+1]);//kt的i要加1是因为题目说两个不重合,所以加1
printf("%d\n",ans);
}
}