最大子序列和的四种求解方法


//最大子序列和问题
#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;
    
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值