4.4最大子段和问题

给定由n个整数组成的序列(a1, a2, …, an),最大子段和问题要求该序列形如图的最大值(1≤i≤j≤n),当序列中所有整数均为负整数时,其最大子段和为0。例如,序列(-20, 11, -4, 13, -5, -2)的 最大子段和为:。

最大子段和问题的分治策略是:

(1)划分:按照平衡子问题的原则,将序列(a1, a2, …, an)划分成长度相同的两个子序列(a1, …, a[n/2]      )和(a[n/2], …, an),则会出现以下三种情况:

① a1, …, an的最大子段和=a1, …,a[n/2] 的最大子段和;

② a1, …, an的最大子段和=a[n/2]+1, …, an的最大子段和;

③ a1, …, an的最大子段和=,且1<=i<=[n\2],[n/2]+1<=j<=n

(2)求解子问题:对于划分阶段的情况①和②可递归求解,情况③需要分别计算。

(3)合并:比较


#include<bits/stdc++.h>

using namespace std;

int MaxSum(int a[],int left,int right)

{

    int sum=0;

    if(left==right)

    {

        if(a[left]>0)sum=a[left];

        else sum=0;

    }

    else

    {

        int center=(left+right)/2;

        int leftsum=MaxSum(a,left,center);

        int rightsum=MaxSum(a,center+1,right);

        int s1=0;int lefts=0;

        for(int i=center;i>=left;i--)

        {

            lefts+=a[i];

            if(lefts>s1)s1=lefts;

        }

        int s2=0;int rights=0;

        for(int j=center+1;j<=right;j++)

        {

            rights+=a[j];

            if(rights>s2)s2=rights;

        }

        sum=s1+s2;

        if(sum<leftsum)sum=leftsum;

        if(sum<rightsum)sum=rightsum;

    }

    return sum;

}

int main()

{

    int a[6]={-20,11,-4,13,-5,-2};

    int b=MaxSum(a,0,5);

    cout<<b;

}
 

在划分阶段的三种情况下的最大子段和,取三者之中的较大者为原问题的解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值