当前位置: 代码迷 >> 综合 >> 51nod 循环数组最大子段和
  详细解决方案

51nod 循环数组最大子段和

热度:103   发布时间:2023-09-20 20:01:02.0

这个问题就是在原来的基础上加上了可以循环。

那么我们可以分两种情况处理,一种是有从尾到头的,例如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;	
}