算法设计第二章作业

利用分治算法求解最大子段和问题C++

将序列一分为二,分别求两个序列的最大子段和,若最大子段和在两个序列之间,为第三种状况。

时间复杂度O(nlog2n)


#include <iostream>
using namespace std;
int MaxSum(int r[], int left, int right)
{
    int Sum = 0, MidSum = 0, LeftSum = 0, RightSum = 0;
    int mid, s1, s2, lefts, rights;
    //如果序列长度为1,那么该值即为最大字段和的结果
    if (left == right)
    {
        Sum = r[left];
    }
    else
    {
        mid = (left + right) / 2;            //所划分的中点mid

        //递归求解左右子序列
        LeftSum = MaxSum(r, left, mid);        //左子序列          
        RightSum = MaxSum(r, mid + 1, right);//右子序列

        //求解左子序列
        s1 = 0; lefts = 0;
        for (int i = mid; i >= left; i--)
        {
            lefts += r[i];
            if (lefts > s1)
            {
                s1 = lefts;
            }
        }
        //求解右子序列
        s2 = 0; rights = 0;
        for (int j = mid + 1; j <= right; j++)
        {
            rights += r[j];
            if (rights > s2)
            {
                s2 = rights;
            }
        }
        //求和
        MidSum = s1 + s2;


        if (MidSum < LeftSum)
        {
            Sum = LeftSum;
        }
        else if (MidSum < RightSum)
        {
            Sum = RightSum;
        }
        else
        {
            Sum = MidSum;
        }
    }
    return Sum;
}

以上是分治法在最大字段中的应用

在此问题中,分治法简化了问题求解的规模和步骤,之后在主函数中进行验证求解即可

接下来是利用python动态规划算法进行求解的代码,时间复杂度:O(n)。

n = int(input())  //输入个数
nums = list(map(int , input().split()))  //输入序列
k = 0 //计算负数个数
for i in nums:
    if i<0:
        k=k+1
if k == len(nums):   //如果全都是负数,则最大字段为0;
    print(0)
else:
    for i in range(1, len(nums))://遍历序列
        nums[i] = max(nums[i], nums[i] + nums[i - 1])  //求解各个子段和

    print(max(nums))  //求解最大子段和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值