最大子段和问题(动态规划)

最大子段和问题(动态规划)

一列数 { a 1 , a 2 , . . . , a n } \{a_1,a_2,...,a_n\} {a1,a2,...,an},求 Σ k = i j a k \Sigma_{k=i}^{j}a_k Σk=ijak的最大值,当最大值小于0时取0。即 m a x { 0 , m a x { Σ k = i j a k } } max\{0,max\{\Sigma_{k=i}^{j}a_k\}\} max{0,max{Σk=ijak}}

  • 一般方法

直接计算 1 < = i < = j < = n 1<=i<=j<=n 1<=i<=j<=n时所有情况的最大值。

int maxSubSum(int *a, int n, int& subidx_i, int& subidx_j)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = i; j < n; j++)
        {
            int temp_num = 0;
            for (int k = i; k <= j; k++)
            {
                temp_num += a[k];
            }
            if (temp_num > sum)
            {
                sum = temp_num;
                subidx_i = i;
                subidx_j = j;
            }
        }
    }
    return sum;
}
  • 一般方法改进

最内层循环出现重复计算,将其去掉。

int maxSubSum(int *a, int n, int& subidx_i, int& subidx_j)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
    {
        int temp_num = 0;
        for (int j = i; j < n; j++)
        {
            temp_num += a[j];
            if (temp_num > sum)
            {
                sum = temp_num;
                subidx_i = i;
                subidx_j = j;
            }
        }
    }
    return sum;
}
  • 分治算法
int maxsubsum(int *a, int begin, int end)
{
    int sum = 0;
    if (begin == end)
        return a[begin] > 0 ? a[begin] : 0;
    int middle = (begin + end) / 2;
    int leftsubsum = maxsubsum(a, begin, middle);
    int righsubsum = maxsubsum(a, middle + 1, end);
    int left = 0, right = 0;
    int temp_left = 0;
    for (int i = middle; i >= begin; i--)
    {
        temp_left += a[i];
        if (temp_left > left)
        {
            left = temp_left;
        }
    }
    int temp_right = 0;
    for (int i = middle + 1; i <= end; i++)
    {
        temp_right += a[i];
        if (temp_right > right)
        {
            right = temp_right;
        }
    }
    sum = left + right;
    if (sum < leftsubsum)
        sum = leftsubsum;
    if (sum < righsubsum)
        sum = righsubsum;
    return sum;
}

int maxSubSum(int *a, int n)
{
    return maxsubsum(a, 0, n - 1);
}
  • 动态规划
int maxSubSum(int *a, int n)
{
    int sum = 0, temp = 0;
    for (int i = 0; i < n; i++)
    {
        if (temp > 0)
        {
            temp += a[i];
        }
        else
        {
            temp = a[i];
        }
        if (temp > sum)
        {
            sum = temp;
        }
    }
    return sum;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值