《算法导论》读书笔记——动态规划与贪心算法【for_wind】

本文探讨了动态规划与贪心算法的区别与联系,并详细解释了这两种算法的设计步骤及应用场景,帮助读者理解何时选用何种算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//整理笔记之算法部分。。。for_wind

1、动态规划

       动态规划适用于子问题不是独立的情况,也就是各子问题包含公共的子子问题。动态规划算法对每个子子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题时重新计算答案。
      如:装配线调度、矩阵链成法、最长公共子序列、最优二叉查找树。

  • 动态规划算法的设计分如下4个步骤

1、描述最优解的结构;
2、递归定义最优解的值;(得到递归式)
3、按自底向上的方式计算最优解的值;
4、由计算出的结果构造出一个最优解。
  • 动态规划方法的最优化问题中的两个要素最优子结构重叠子问题
  • 最优子结构
  • 寻找最优子结构时候,可以遵循一种共同的模式:

  1. 问题的一个解可以是做一种选择。做这种选择会得到一个或多个有待解决的子问题。
  2. 假设对一个给定的问题,已知的是一个可以导致最优解的选择。不必关心如何确定这个选择,尽管假定它是已知的。
  3. 在已知这个选择后,要确定哪些子问题会随之发生,以及如何最好地描述所得到的子问题空间。
  4. 利用一种“剪贴”技术,来证明问题的一个最优解中,使用的子问题的解本身也必须是最优的。
  • 最优子结构在问题域以两种方式变化
  1. 多少子问题被使用在原问题的一个最优解中,以及
  2. 决定一个最优解中使用哪些子问题时有多少个选择
      动态规划自底向上的方式来利用最优子结构。首先找到子问题的最优解,解决子问题,然后找到问题的一个最优解。寻找问题的一个最优解需要在子问题中做出选择,即选择哪一个来求解问题。问题解的代价通常是子问题的代价加上选择本身带来的开销
      贪心算法是以自顶向下的方式来使用最优子结构。贪心算法先做选择,在当时看来是最优的选择,然后再求解一个结果的子问题,而不是先寻找子问题的最优解,然后再做选择。
  • 重叠子问题
  • 动态规划要求子问题既要独立又要重叠。即:同一个问题的两个子问题不共享资源(独立),同一个子问题会作为不同问题的子问题出现(重叠)。

  • 做备忘录(动态规划的变形)
      自顶向下的做备忘的递归算法。在实际应用过程中,如果所有子问题都至少要被计算一次,则自底向上的动态规划算法要比自顶向下的做备忘的算法要好出一个常数因子,因为前者无需递归的代价,而且维护表格的开销要小些。而如果子问题空间中的某些子问题根本没有必要求解,做备忘方法有着只解那些肯定要求解的子问题的优点。

2、贪心算法

  • 贪心算法:活动选择问题;任务调度问题;数据压缩(huffman)编码的设计;最小生成树;Dijkstra的单源最短路径。
  • 贪心算法的设计步骤:
  1. 将优化问题转换成这样的一个问题:即先做出选择,再解决剩下的子问题。
  2. 证明原问题总是由一个最优解是做贪心选择得到的,从而证明贪心选择的安全性。
  3. 说明在做出贪心选择后,剩余的子问题具有这样的一个性质。即如果将子问题的最优解和我们所做的贪心选择联合起来后,可以得出原问题的一个最优解。
  • 贪心选择性质
      贪心选择的性质:一个全局最优解可以通过局部最优(贪心)选择来达到。换句话说,当考虑做如何选择时候,我们只考虑对当前问题最佳的选择不考虑子问题的结果
  • 以上这一点是贪心算法不同与动态规划之处:
    • 在动态规划中,每一步都要做出选择,但是这些选择依赖于子问题的解。因此解动态规划问题一般是自底向上,从小子问题处理至大子问题。
    • 在贪心算法中,我们所做的总是当前看似最佳的选择,然后在解决选择之后所出现的子问题。贪心算法年所做的当前选择可要依赖于已经做出的所有选择,当不依赖于有待做出的选择或子问题的解。贪心策略通常是自顶向下地做的,一个一个的做出贪心选择,不断的将给定的问题实例规约为更小的问题。
  • 贪心算法使用最优子结构,通常是更加直接的方式。假设原问题做了一个贪心选择而得到一个子问题。真正要做的是证明此子问题的最优解与所做的贪心选择合并后,的确可以得到原问题的一个最优解。
  • 0-1背包部分背包问题:
      0-1背包之为什么不能用贪心算法解决?
      因为当无法将背包填满,空余的空间降低了该背包内货物的有效单位价值。
      在0-1背包问题中,当我们在考虑是否要把一件物品加到背包中时,必须对把该物品加进去的子问题的解与不取该物品的子问题的解进行比较。导致许多重叠子问题,可以采用动态规划来解决。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值