//最大子序列和问题
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100 + 5;
//分治
int maxz(int a[],int x,int y)//返回数组左闭右开区间的最大和
{
int v = 0,l,r,maxs;
if(y - x == 1)return a[x];
int m = x + (y - x) / 2;//分治第一步:划分成[x,m),[m,y);
int maxs = max(maxz(a,x,m),maxz(a,m,y));//分治第二步递归求解
l = a[m - 1];
for(int i = m - 1;i >= x;i--){//分治的第三部合并,从分界点开始往左的最大连续和
l = max(r,v += a[i]);
}
v = 0;r = a[m];
for(int i = m;i < y;i++){//分治第三步,从分界点往右的最大连续和
r = max(r,v += a[i]);
}
return max(maxs,l + r);//把子问题与l+r比较
}
int main()
{
int a[maxn],n;
int ans = 0;
int i,j,k,man,sum[maxn],minn = 10000;
cin>>n;
for(i = 0;i < n;i++){
cin>>a[i];
}
for(i = 0;i < n;i++){
man = max(0,man) + a[i];//以i结尾的最大前n项和
ans = max(man,ans);
}
cout<<ans<<endl;
//第二种动态规划
sum[0] = a[0];
for(int i = 1; i < n - 1;i++){
sum[i + 1] = sum[i] + a[i];
}
for(int i = 0;i < n;i++){
minn = min(minn,sum[i]);
ans = max(ans,sum[i] - minn);
}
cout<<ans<<endl;
//暴力解决
for(i = 0;i < n;i++){
for(j = i;j < n;j++){
for(k = i;k < j;k++){
sum[k] = a[i] + a[j]; //从i加到j的和
}
ans = max(ans,sum[k]);//得到每一个区间的最大和
}
}
//简单的优化
sum[0] = a[0];
for(i = 1;i < n - 1;i++){
sum[i + 1] = sum[i] + a[i];
}
for(i = 0;i < n;i++){
for(j = i;j < n;j++){
ans = max(ans,sum[j] - sum[i - 1]);
}
}
cout<<maxz(a,0,x)<<endl;
}
最大子序列和的四种求解方法
最新推荐文章于 2021-10-21 23:16:54 发布