一、伪代码描述最大字段和的分治算法
//共三种情况:
//1. 最大字段和为左半段的和
//2. 最大字段和为右半段的和
//3. 最大字段和跨越左右两边
#include<bits/stdc++.h>
using namespace std;
int a[100010],s[100010];
int solve(int left, int right)
{
if(left==right) //子问题只有一个,大于0就返回该数
{
if(a[left]<0) return 0;
return a[left];
}
int mid=(left+right)/2;
int sl=solve(left, mid), sr=solve(mid+1, right);
int s1=0, t=0;
for(int i=mid; i>=left; i--) //从中间往左一直累加,直到得到最大值
{
t+=a[i];
s1=max(t, s1);
}
int s2=0;
t=0;
for(int i=mid+1; i<=right; i++) //从中间往右一直累加,直到得到最大值
{
t+=a[i];
s2=max(t, s2);
}
int sm=s1+s2; //第三种情况,最大字段和跨域左右两边
return max(sm, max(sl, sr));
}
int main()
{
int n;
cin>>n;
bool f=1;
for(int i=1; i<=n; i++)
{
cin>>a[i];
if(a[i]>=0) f=0;
}
cout<<solve(1, n);
int ma=-1, now=0;
for(int i=1; i<=n; i++)
{
if(now+a[i]>0)
{
now+=a[i];
ma=max(ma, now);
}
else now=0;
}
if(f) cout<<0;
else cout<<ma;
return 0;
}
二、该算法的时间复杂度
O(n)=nlogn
三、结合本章的学习,你对分治法的体会和思考
1.分治,即分⽽治之,是将⼀个规模为n的问题分解为k个规模较⼩的⼦问题,这些⼦问题互相独⽴且与原问题相同。
2.在进行代码编写前,需要合理地对问题进行拆分,使子问题的规模都大致相同,同时也要学会计算算法的时间复杂度。
3.对于一些规模较大且可以被划分的问题,分治法能够有效地提高问题的求解效率和性能。