最大子段和问题求解思路总结

方法1、分治求解求最大子段和

思路:
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题。
对于一个序列来说,它的最大值有三种情况,第一种是左半部分的最大值,第二种是右半部分的最大值,第三种是左半部分右边的最大值+右半部分左边的最大值(有点类似于线段树维护最大和的问题)。

#include<bits/stdc++.h>
using namespace std;

const int N  = 5e4 + 10;
int a[N], n;

int maxsum(int l, int r){
    if(l == r) return max(0, a[l]);
    int mid = l + r >> 1;
    int lmax = maxsum(l, mid);
    int rmax = maxsum(mid + 1, r);
    //left
    int ls = 0, tmp1 = 0;
    for(int i = mid; i >= l; i--){//倒着算,因为要求左半边的右部最大和右半边的左部最大的和
        tmp1 += a[i];
        ls = max(ls, tmp1);
    }
    //right
    int rs = 0, tmp2 = 0;
    for(int i = mid + 1; i <= r; i ++){
        tmp2 += a[i];
        rs = max(rs, tmp2);
    }
    int maxs = ls + rs;
    return max(maxs, max(lmax, rmax));
}

signed main(){
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    cout << maxsum(1, n);
    return 0;
}
posted @ 2022-11-03 11:45  风归去  阅读(90)  评论(0编辑  收藏  举报