直接算法+动态规划算法求解最大子段和

问题介绍:
在一个有限序列,任意连续的序列的和的最大值,记为最大子段和。
直接算法:
确切的说是改进后的直接算法,时间复杂度是O(n^2)
动态规划算法
规定当子段和为负整数时,字段和为0;
时间复杂度是O(n);
改进的直接算法代码:

/*
 * 求最大子段和的原始版的改进版
 * 时间复杂度O(n^2)
*/

#include <iostream>
using namespace std;

MaxSubSum(int n ,int a[], int &besti,int &bestj){
    int sum=0;
    int i,j;
    for(i=0;i<n;i++){
        int thissum=0;
        for(j=i;j<n;j++){//在遍历的时候顺便把临时最大子段和给求出来
            thissum+=a[j];
            if(thissum>sum){
                sum=thissum;
                besti=i;
                bestj=j;
            }
        }
    }
    return sum;
}

int main(){
    int besti,bestj;
    besti=bestj=0;
    int a[5]={-1,2,3,-4,1};
    cout<<MaxSubSum(5,a,besti,bestj)<<endl;
    cout<<"("<<besti<<","<<bestj<<")"<<endl;
    return 0;
}

动态规划算法代码:

/*
 *动态规划求最大子段和
 * besti,bestj记录最大子段的开始下标和结束下标
 * 时间复杂度O(n)
 * */

#include <iostream>
using namespace std;

MaxSubSum(int n,int a[],int &besti,int &bestj){
    int sum =0,b=0;
    int j;
    for(j=0;j<n;j++){
        b+=a[j];
        if(b<0){
            b=0;
            besti=j+1;//一旦b<0,抛弃前面的结果,把j的下一个位置记录下来
            bestj=j+1;
        }
        if(b>sum){
            sum=b;
            bestj=j;//bestj跟着sum更新而更新
        }
    }
    return sum;
}

int main(){
    int besti,bestj;
    besti=bestj=0;
    int a[5]={8,-1,3,2,-1};
    cout<<MaxSubSum(5,a,besti,bestj)<<endl;
    cout<<besti<<" "<<bestj<<endl;
}

猜你喜欢

转载自blog.csdn.net/liunan199481/article/details/78633056