紫书第八章-----高效算法设计(算法分析初步)

最大连续子序列和算法
本文探讨了求解最大连续子序列和问题的四种不同算法思路:暴力枚举、递推前缀和、分治法及动态规划,并通过具体代码实现展示了每种方法的优缺点。
/*
    本程序参考刘汝佳《算法竞赛入门经典》(第2版)
    下面的题目,不断优化,程序时间复杂度逐渐变小。
    【题目叙述】
        给出一个长度为N的序列:a1,a2,……,an,求最大连续和。
    找到1=<I<=J<=N,使得ai+a(i+1)+……+aj尽量大。
*/

#include<iostream>

using namespace std;

//数组下标从1开始

//思路一:暴力枚举
int max_sum1(int a[],int n){
    int best=a[1];
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            int sum=0;
            for(int k=i;k<=j;k++) sum+=a[k];
            if(sum>best) best=sum;
        }
    }
    return best;
}

//思路二:递推前n项和
int max_sum2(int a[],int n){
    int best=a[1];
    int *s=new int[n+1];
    s[0]=0;
    for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++)
            best=max(best,s[j]-s[i-1]);
    }
    delete[] s;
    return best;
}

//思路三:分治法
//左闭右开区间
int max_sum3(int a[],int x,int y){
    int v,l_sum,r_sum,best;
    if(y-x==1) return a[x];
    int mid=x+(y-x)/2;
    best=max(max_sum3(a,x,mid),max_sum3(a,mid,y));
    v=0;l_sum=a[mid-1];
    for(int i=mid-1;i>=x;i--) l_sum=max(l_sum,v+=a[i]);
    v=0;r_sum=a[mid];
    for(int i=mid;i<y;i++) r_sum=max(r_sum,v+=a[i]);
    return max(best,l_sum+r_sum);
}

//思路四:动态规划
int max_sum4(int a[],int n){
    int best=a[1],cur_sum=0;//cur_sum表示到目前状态下的最大连续和
    for(int i=1;i<=n;i++){
        if(cur_sum<=0) cur_sum=a[i];
        else cur_sum+=a[i];
        best=max(best,cur_sum);
    }
    return best;
}

int main()
{
    int a[7]={0,3,4,-6,4,5,-2};
    cout<<max_sum1(a,6)<<endl;
    cout<<max_sum2(a,6)<<endl;
    cout<<max_sum3(a,1,6)<<endl;
    cout<<max_sum4(a,6)<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值