最大子段和

问题描述:
给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。

当所有整数均为负值时定义其最大子段和为0。
依此定义,所求的最优值为:
 
例如,当(a1,a2 , a3 , a4 , a5 ,a6)=(-2,11,-4,13,-5,-2)时,

最大子段和为:

11+(-4)+13 =20


一个最简单的算法是:

int maxdata[9]={-2, 1, -3, 4, -1, 2, 1, -5, 4};

int maxsubarray(){
    int  max_ending_here;
    int  max_so_far;
    max_ending_here=0;
    max_so_far=0;
    for(int i=0;i<9;i++){
        max_ending_here = maxvalue(0, max_ending_here + maxdata[i]);
        max_so_far = maxvalue(max_so_far, max_ending_here);
       
    }
    return max_so_far;
}

如果采用分治法,时间复杂度为O(nlogn),代码如下:

int MaxSubSum(int * Array, int left, int right){
    int sum=0;
    int i;
    if(left==right){
        if(Array[left]>0)
            sum=Array[left];
        else
            sum=0;
    }else{
        int center=(left+right)/2;
        int leftsum=MaxSubSum(Array, left, center);
        int rightsum=MaxSubSum(Array, center+1, right);
        
        int s1=0;
        int lefts=0;
        for(i=center;i>=left;i--){
            lefts=lefts+Array[i];
            if(lefts>s1)
                s1=lefts;
        }
        int s2=0;
        int rights=0;
        for(i=center+1;i<=right;i++){
            rights=rights+Array[i];
            if(rights<s2)
                s2=rights;
        }
        
        sum=s1+s2;
        if(sum<leftsum) sum=leftsum;
        if(sum<rightsum) sum=rightsum;
        
    }
    return sum;
    
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值