最长子段和 动态规划算法

动态规划算法的介绍

在第一篇动态规划算法中简单介绍了一下动态规划算法
矩阵连乘积问题及动态规划算法介绍

最长子段和问题

问题介绍:

给定由n个整数(包含负整数)组成的序列a1,a2,…,an,求该序列子段和的最大值。
当所有整数均为负值时定义其最大子段和为0。
所求的最优值为:
在这里插入图片描述

举例解释:

例如: 当(a1,a2, ……a7,a8)=(1,-3, 7,8,-4,12, -10,6)时,最大子段和为:
在这里插入图片描述

该问题可以使用蛮力法、分治法、动态规划法进行编程
此处只介绍动态规划算法

一、分析最优子结构

设bj是1到j区间的最大子段和(1j,2j,…j~j,共j个子段):
在这里插入图片描述
在这里插入图片描述
则所求的最大子段和为:
在这里插入图片描述

最大子段和的动态规划计算过程
在这里插入图片描述
在这里插入图片描述

二、建立递归关系

  • 由bj的定义易知, 当bj-1>0时 bj=bj-1+aj, 否则 bj=aj。 则计算bj的动态规划递归式:
    bj=max{bj-1+aj,aj},1≤j≤n。
    在这里插入图片描述

三、求解最优值

#define NUM 1001
int a[NUM];
int MaxSum(int n){
    int sum=0; //最大子段和
    int b=0; //1~j的最大子段和,因无需保留其他结果,所以没必要定义数组
    for (int j=1;j<=n;j++)
    {
  	if (b>0) 
	    b+=a[j]; 
	else
	    b=a[j];
	if (b>sum) sum=b;
    }    return sum;
}

在这里插入图片描述
显然该算法的计算时间为O(n)

四、计算最优解

计算最大子段和的动态规划算法的最优解
令besti,bestj为最大子段和sum的起始位置和结束位置;
在当前位置i,如果b[i-1] ≤0时,在取b[i]=a[i] 的同时,保存该位置i到变量begin中,显然:
当b(i-1)≤0时,begin=i;
当b(i)≥sum时,besti=begin,bestj=i。

在这里插入图片描述

计算最大子段和的动态规划算法的最优解
#define NUM 1001
int a[NUM];
int MaxSum(int n, int &besti, int &bestj){
  int sum=0;   int b=0;  int begin = 0;
  for (int i=1; i<=n; i++){
        if (b>0)  b+=a[i]; 
        else {b=a[i]; begin = i;}
        if (b>sum) {//得到新的最优值时,更新最优解
	sum = b; 
	besti = begin; 
	bestj = i;
	}
  }
  return sum;
}
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值