方法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;
}
标签:求解,int,最大值,子段,mid,ls,思路,tmp1,maxsum
From: https://www.cnblogs.com/N-lim/p/16853920.html