动态规划是啥?

动态规划是一种解决最优化问题的方法,适用于子问题重叠的情况。文章通过钢条切割问题介绍动态规划的四个步骤,并探讨自顶向下(带备忘录)和自底向上的实现方式。动态规划通过避免重复计算子问题,提高了效率。
摘要由CSDN通过智能技术生成

01 动态规划

动态规划(dynamic programming)与分治法相似, 都是通过组合子问题的解来求解原问题. 分治方法将问题划分为互不相交的子问题, 递归地求解子问题, 在将它们的解组合起来, 求出原问题的解. 而动态规划应用与子问题重叠的情况, 即不同的子问题具有公共的子问题. 对于分治法来说会重复的计算公共的子问题. 而动态规划对子问题只求解一次, 将结果保存到表格中(相当于缓存),以后用的时候直接取出即可.

动态规划通常用来求解最优化问题. 比如咱们使用地图导航寻找最短路径问题等.

动态规划算法的4个步骤:

1、找到最优解的结构特征, 这步其实最难.

2、递归地定义最优解的值.

3、计算最优解的值, 通常采用自底向上的方法.

4、利用计算出的信息构造一个最优解.

02 动态规划样例: 钢条切割

在这里插入图片描述
此表表示钢条的长度带来的价格, 比如长度为8的钢条带来20元的收益.
问题是这样: 给定一段长度为n英寸的钢条和一个价格表pi(如上图), 求切割钢条方案, 使销售收益rn最大. 若长度为n英寸的钢条价格pn足够大, 最优解可能就是完全不需要切割.
长度为n英寸的钢条共有2的n-1次方种不同的切割方案, 因为在距离钢条左端i英寸处, 总是可以选择切割或不切割. 我们用7 = 2 + 2 + 3 表示长度为7英寸的钢条切割为三段. 两段长为2英寸, 一段长为3英寸. 若一个最优解将钢条切割为k段, 那么最优切割方案 n = i1 + i2 + i3 + …+ ik, 得到的最大收益为rn = pi1+pi2+…+pik. 我们对应上表最优收益值及对应的最优切割方案:
在这里插入图片描述
上面理解起来应该不难, 更一般地, 对于rn(n>=1), 最优收益我们记为:
rn = max(pn, r1+r(n-1), r2 + r(n-2),…, r(n-1) + r1), 第一个参数pn对应不切割, 直接出售长度为n英寸的钢条的方案. 其他n-1个参数对应另外n-1种方案: 对每个i=1, 2,…,n-1, 首先将钢条切割为长度为i和n-i两段, 接着求解这两段的最优切割收益ri和r(n-i),(每种方案的最优收益为两段的最优收益之和). 由于无法知道哪种方案会获得最优收益, 我们必须考察所有可能的i, 选出收益最大的.
最优子结构: 问题的最优解由相关子问题的最优解组合而成, 而这些子问题可以独立求解.

03 自顶向下递归实现

# coding=utf-8


def CUT_ROD(p, n):
    """
    自顶向下递归实现
    """
    q = -65535
    if n == 0:
        return 0
    for i in range(0, n):
        q = max(q, p[i] + CUT_ROD(p, n-i-1))
    return q


if __name__ == '__main__':
    p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小筑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值