就是三种状态想出来就行了,开始想出来两种,看了一组测试数据想了一种。
1.正常的最大连续序列2.开始在尾,结束的首第一种正常求,第二种考虑答案的组成,开始的一段+到结尾的一段,那么中间为什么去掉呢,因为中间那段和为负数,只要求出负数最大的连续子序列去掉就行了max(ans1,sum+ans2);中间那段挖空了,所以首尾要接起来,总和减去那段负数的最大连续字段就行了,
#include<bits/stdc++.h>
using namespace std;
long long a[51000],maxn,now,first,min1=0,tmp,sum=0;
int main(){
int n,flag=0;
tmp=0;
ios::sync_with_stdio();
first=maxn=now=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
now+=a[i];
tmp-=a[i];
min1=max(min1,tmp);
if(tmp<0)tmp=0;
maxn=max(maxn,now);
if(now<0)
{
now=0;
if(flag==0)first=maxn;
flag=1;
}
}
//cout<<maxn<<endl;
first+=now;
maxn=max(maxn,sum+min1);
maxn=max(maxn,first);
cout<<maxn<<endl;
return 0;
}