题目描述 Description
N个数围成一圈,要求从中选择若干个连续的数(注意每个数最多只能选一次)加起来,问能形成的最大的和。
输入描述 Input Description
第一行输入N,表示数字的个数,第二行输入这N个数字。
输出描述 Output Description
输出最大和。
样例输入 Sample Input
8
2 -4 6 -1 -4 8 -1 3
样例输出 Sample Output
14
数据范围及提示 Data Size & Hint
数据说明:
40% 1<=N<=300
60% 1<=N<=2000
100% 1<= N<=100000,答案在longint范围内。
分类标签 Tags 点此展开
暂无标签
解题思路:
1、错解:
第一次想用线段树维护一下区间最大,搞了n次只过40%数据,听zjk说这题线段树不好维护,mxx不好维护有环区间的最大值。
2、正解:
环形的最大连续子段和有两种情况,一种是在1~n的,或者是在1~2*n的,如果是在
1~2*n中,显然可知ans等于sum减去1~n中的最小连续字段和
AC代码:
#include<cstdio> #include<iostream> using namespace std; const int N=1e5+10; const int inf=0x7fffffff; int n,maxn=-inf,minn=inf,sum,f[N],a[N]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i]; for(int i=1;i<=n;i++) f[i]=f[i-1]>0?f[i-1]+a[i]:a[i],maxn=max(maxn,f[i]); for(int i=1;i<=n;i++) f[i]=f[i-1]<0?f[i-1]+a[i]:a[i],minn=min(minn,f[i]); printf("%d ",max(maxn,sum-minn)); return 0; }