这个问题就是在原来的基础上加上了可以循环。
那么我们可以分两种情况处理,一种是有从尾到头的,例如1表示取,0表示不取,则是11000011
一种是没有跨越的, 即000111100
那么对于第二种情况可以直接用最大字段和做,关键是第一段要怎么处理。
这里需要用到逆向思维,在1110000111这一个答案中,0000是最小字段和,因为总和是一定的 。
那么我们就可以用类似的方法算出最小字段和,然后用总和一减就ok了。
最后两种情况取max就是答案。
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
typedef long long ll;
const int MAXN = 51234;
int a[MAXN], n;
ll ans, sum, ans1, ans2;
int main()
{
scanf("%d", &n);
REP(i, 0, n) scanf("%d", &a[i]), sum += a[i];
ll t = 0;
REP(i, 0, n) t = min((ll)a[i], t + a[i]), ans = min(ans, t);
ans1 = sum - ans;
t = 0;
REP(i, 0, n) t = max((ll)a[i], t + a[i]), ans2 = max(ans2, t);
printf("%lld\n", max(ans1, ans2));
return 0;
}