循环数组的最大子段和

N个整数组成的循环序列a11,a22,a33,…,ann,求该序列如aii+ai+1i+1+…+ajj的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑an1n−1,ann,a11,a22这样的序列)。当所给的整数均为负数时和为0。
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。

Input第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N+1行:N个整数 (-10^9 <= Sii <= 10^9)Output输出循环数组的最大子段和。Sample Input

6
-2
11
-4
13
-5
-2

Sample Output

20

循环的,则有两种情况,一种是最大字段在中间,一种是在两边,在中间的可直接求,在两边需要取负求出最小子段和,总值减去即可得最大,中间两边
取大即可
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
typedef long long ll;
ll n;
int a[maxn];
ll cmp()
{
    ll x1=0,y1=0;
    for(int i=0;i<n;i++)
    {
        if(x1<0)
            x1=a[i];
        else
        {
            y1=max(y1,x1);
            x1+=a[i];
        }
    }
    return y1;
} 
int main()
{
    ll sum=0;
    ll cnt1=0,cnt2=0;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        sum+=a[i];
    }
    cnt1=cmp();
    for(int i=0;i<n;i++)
        a[i]=-a[i];
    cnt2=cmp();
    sum=max(cnt1,sum+cnt2);
    cout<<sum<<endl;    
    return 0;
}
原文地址:https://www.cnblogs.com/ylrwj/p/12298568.html