循环数组最大子段和(动态规划)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050

两种情况:

1 最大子段和没有循环

第i个位置的最大子段和由它i-1的最大子段和决定。dp[i-1]>=0,则dp[i]=dp[i-1]+a[i];dp[i-1]<0,dp[i]=a[i](本身)

2 最大字段和有循环

说明中间有一段字段和是负数,那么可以将所有数取相反数,算出相反数的最大字段和加到所有数的和上,就相当于和减去最小字段和为最大字段和

#include<iostream>
#include<algorithm>
#define MAXLEN 50005
#define LL long long
using namespace std;

LL Maximum_Interval_Sum(int a[], int len)
{
    LL dp[MAXLEN] = { 0 }, maxn = a[0];
    dp[0] = a[0];
    for (int i = 1; i < len; i++)
    {
        if (dp[i - 1] >= 0)
            dp[i] = a[i] + dp[i - 1];
        else
            dp[i] = a[i];
        maxn = max(dp[i], maxn);
    }
    return maxn;
}
int main()
{
    int n, a[MAXLEN], b[MAXLEN];
    LL sum = 0;

    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
        b[i] = -a[i];
        sum += a[i];
    }
    LL mid = Maximum_Interval_Sum(a, n);
    LL head_tail = sum + Maximum_Interval_Sum(b, n);
    cout << max(mid, head_tail);
    //system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/NDKY9/p/8029483.html