【算法】最大子列和问题

方法一:暴力破解。(O(n^3))

#include <iostream>

int MaxSubseqSum1(int A[],int n){
    int ThisSum, MaxSum=0;
    for(int i=0;i<n;i++)
        for(int j=i;j<n;j++){
            ThisSum=0;
            for(int k=i;k<=j;k++)
                ThisSum+=A[k];
            if(MaxSum<ThisSum) MaxSum=ThisSum;
        }
    return MaxSum;
    
};

int main(){
    int a[7]={1,2,3,4,5,6,7};
    int n=7;
   std::cout<<MaxSubseqSum1(a, n);

    return 1;
}

方法二:优化为(O(n^2))

#include <iostream>

int MaxSubseqSum1(int A[],int n){
    int ThisSum, MaxSum=0;
    for(int i=0;i<n;i++)
    {
        ThisSum=0;
        for(int j=i;j<n;j++){
            ThisSum=ThisSum+A[j];
            if(MaxSum<ThisSum) MaxSum=ThisSum;
        }
    }
    return MaxSum;
    
};

int main(){
    int a[7]={1,2,3,4,5,6,7};
    int n=7;
   std::cout<<MaxSubseqSum1(a, n);

    return 1;

方法三:优化为(O(nlogn)) 分治

#include <iostream>
int Max3(int a,int b,int c){
    return a>b?(a>c?a:c):(b>c?b:c);
}

int MaxSubseqSum1(int A[],int left,int right){
  
  if (left == right) {            //分治毕竟是递归,递归的起点是要写的
        if(A[left] > 0)
            return A[left];
        else
            return 0;
    }

    int mid=(left+right)/2;
    
    int LeftSum=MaxSubseqSum1(A, left,mid);//这里要注意,不要把left写成0哦
    int RightSum=MaxSubseqSum1(A, mid+1,right);
    
    int LeftPart=0;
    int MaxLeftPart=0;
    for(int i=mid;i>=left;i--){//这里的更新要注意,左边依次地去加,如果产生的sum比原来大,更新这个sum
        LeftPart+=A[i];
        if(LeftPart>MaxLeftPart)
            MaxLeftPart=LeftPart;
    }
    
    int RightPart=0;
    int MaxRightPart=0;
    for(int i=mid+1;i<=right;i++){
        RightPart+=A[i];
        if(RightPart>MaxRightPart)
            MaxRightPart=RightPart;
    }
    
    int MidSum=MaxLeftPart+MaxRightPart;
    return Max3(LeftSum, RightSum, MidSum);
};

int main(){
    int a[5]={-6,7,4,-3,1};
    int n=5;
    std::cout<<MaxSubseqSum1(a, 0,n-1);

    return 0;
}

算法四,优化为(O(n)):在线算法
依次选取每个元素作为起点,向右取一段序列求和。不断更新过程中获得的最大的sum,如果sum变为负数,则更换下一个元素。其主要的观察就是,如果一个序列的第一个位置为负数,那么这个序列一定不是最大和序列(必可以把该首元素去掉)

#include <iostream>

int MaxSubseqSum1(int A[],int N){
    int thisSum=0,MaxSum=0;
    for(int i=0;i<N;i++){
        thisSum+=A[i];
        if(thisSum>MaxSum) MaxSum=thisSum;
        else if(thisSum<0) thisSum=0;//这一句是画龙点睛之笔哦。thisSum本身如果超过了maxsum就更新maxsum
    }
    return MaxSum;
};

int main(){
    int a[5]={-6,7,4,-3,1};
    int n=5;
    std::cout<<MaxSubseqSum1(a,n);
    return 0;
}
原文地址:https://www.cnblogs.com/maxwell-maxwill/p/12306549.html