最大子列和问题
基于 陈越的数据结构课的第一个算法
这个问题现在来看,给一组数,求这组数的最大子列和
在线处理
1.如果只是求整个区间的最大子列和,在线处理是最优解
这个主要记住在线的概念:每输入一个数据就及时处理,在任何一个地方终止输入,算法都能正确给出当前的解
cin>>n;
for(int i=1;i<=n;i++){
cin>>k;
nowsum+=k;
if(nowsum>maxsum)maxsum=nowsum;
if(nowsum<0)nowsum=0;
}
cout<<maxsum<<endl;
分而治之(O(nlogn))
2.用分而治之的算法,O(nlogn)的算法其实也是后面线段树的一个基础,只是求的是整个区间(这种方法很多区间的问题都有用到)
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define iloves ios::sync_with_stdio(false);cin.tie(0);
#define int long long
const int MAX_N = 1e5 + 10;
int List[MAX_N], n, k, nowsum, maxsum;
int DivideandConquer(int l, int r) {
int Maxleftsum, Maxrightsum;
if (l == r) {
if (List[l] > 0)return List[l];
else return 0;
}
int mid = (l + r) >> 1;
Maxleftsum = DivideandConquer(l, mid);
Maxrightsum = DivideandConquer(mid + 1, r);
int MaxleftBordersum=0,LeftBordersum=0;
for(int i=mid;i>=l;i--){
LeftBordersum+=List[i];
if(LeftBordersum>MaxleftBordersum)MaxleftBordersum=LeftBordersum;
}
int MaxrightBordersum=0,RightBordersum=0;
for(int i=mid+1;i<=r;i++){
RightBordersum+=List[i];
if(RightBordersum>MaxrightBordersum)MaxrightBordersum=RightBordersum;
}
return max({Maxleftsum,Maxrightsum,MaxleftBordersum+MaxrightBordersum});
}
void slove() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> k;
List[i] = k;
}
cout << DivideandConquer(1, n) << endl;
}
signed main() {
iloves;
int test = 1;
while (test--) {
slove();
}
return 0;
}
### 线段树(区间查)
3.如果要查询某个区间的最大子列和,显然,用线段树来做会方便很多(学过,但没完全学会,所以没代码)