最大子段和

给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。(题面即解释)

现在我们可以将题目分为几个部分来看。
1. 左段:left – mid部分的最大值
2. 右段: mid+1 – right部分的最大值
3. 将中间两段合并的最大值

#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;

ll a[200010], n;
const ll minnum = -999999;

ll max_sum(ll left, ll right)
{
    if (left == right) return a[left];
    ll mid = (left + right) / 2;
    ll sum1 = 0, sum2 = 0;
    ll sum_left = minnum, sum_right = minnum;
    for (ll i = mid; i >=left; i--)            //从left - mid的最大值
    {
        sum1 += a[i];
        sum_left = max(sum_left, sum1);
    }
    for (ll i = mid + 1; i <= right; i++)      //从mid+1 - right的最大值
    {
        sum2 += a[i];
        sum_right = max(sum_right, sum2);
    }
    return max(max(max_sum(left, mid), max_sum(mid + 1, right)), sum_left + sum_right);    //第3种情况为中间合并时的值,将其3种情况比较最大值

}


int main()
{
    cin >> n;
    for (ll i = 1; i <= n; i++)
        cin >> a[i];
    cout << max_sum(1, n) << endl;
    return 0;
}

运行结果:

分类: 算法集

0 条评论

发表评论

Avatar placeholder

邮箱地址不会被公开。 必填项已用*标注