题目描述
给定一个长度为n的整数序列,要求从中选出两个连续子序列,使得这两个连续子序列的序列和之和最大,最终只需输出最大和。一个连续子序列的和为该子序列中所有数之和。每个连续子序列的最小长度为1,并且两个连续子序列之间至少间隔一个数。
输入输出格式
输入格式:
第一行是一个整数表示n。
第二行是n个整数表示整数序列。
输出格式:
一个数,两个连续子序列的序列和之和。
输入输出样例
输入样例#1: 复制
5
83 223 -13 1331 -935
输出样例#1: 复制
1637
输入样例#2: 复制
3
83 223 -13
输出样例#2: 复制
70
说明
对于30%的数据N<=100。
对于60%的数据有N<=10000。
对于100%的数据有N<=1000000。
数据保证运算过程不会超过long long(int64)。
思路
分别求从左到右的以及从右到左的当前子串和和当前最大子串和
#include<cstdio>
#include<iostream>
using namespace std;
const int N=1000005;
long long ans,a[N],f[N],g[N],s;
int main()
{
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)
cin>>a[i];
f[1]=a[1];
s=a[1];
for(i=2;i<=n;i++)
{
s=max(a[i],s+a[i]);
f[i]=max(f[i-1],s);
}
g[n]=a[n];
s=a[n];
for(i=n-1;i>=1;i--)
{
s=max(a[i],s+a[i]);
g[i]=max(g[i+1],s);
}
ans=a[1]+a[3];
for(int i=2;i<n;i++)
ans=max(ans,f[i-1]+g[i+1]);
cout<<ans<<endl;
return 0;
}