算法系列(三):动态规划

算法介绍

策略

将原问题递归地分解成子问题,之后再由所有子问题的解构造出最终解。

与分治法的区别

  • 分治法将原问题分解成多个子问题,独立地求解每个子问题,并对所有解进行组合获得最终解,比如快速排序
  • 动态规划同样做了分解原问题的步骤,但是分解获得的子问题是叠加的,这意味着动态规划更适用于“原问题可分解为叠加的子问题”的情况。

使用条件

  1. 最优子结构(贪心章节有讲到)
  2. 无后效性
    存在状态转移方程,使得转移后的状态不需要考虑转移前的状态。
  3. 子问题重叠性质
    子问题间不独立

一般步骤

1.将问题分解成叠加的子问题
2.递归地求解子问题
3.由子问题的解构造最终解
(至此讲的确实抽象,写使用条件以及步骤是为了突出该算法的特征,如果上来就给个例子,后面复习时可能需要通过思考例子来重复地提取出算法的骨架,影响效率)

举例

0-1背包问题

问题描述
现有1个背包容量为C,有N个物品,其中第 i 个物品重量为 W i W_i Wi,价值为 V i V_i Vi。问如何装使得总体价值最高。

问题分析
首先这个问题规模是有限的,可以遍历所有解,因此可以用蛮力法求解,时间复杂度为 O ( 2 n ) O(2^n) O(2n),要考虑更优解法;具有最优子结构,考虑贪心法,每一次选择都会减少背包的剩余容量,对下一个选择有影响,故没有贪心选择性质,推断贪心法不能获得最优解;具有无后效性和子问题重叠性质,考虑动态规划,条件满足,尝试求解。

问题求解
d p [ i ] [ C ] dp[i][C] dp[i][C]表示在容量为 C C C的背包中放入前 i i i件物品获得的最大价值,
则动态规划状态转移方程如下 d p [ i ] [ C ] = m a x ( d p [ i − 1 ] [ C ] , d p [ i − 1 ] [ C − W i ] + V i ) dp[i][C]=max(dp[i-1][C],dp[i-1][C-W_i]+V_i) dp[i][C]=max(dp[i1][C],dp[i1][CWi]+Vi)其中,等式右边的前半部分表示不放入第 i i i件物品,后半部分表示放入第 i i i件物品。

程序示例(python)
懒得写 :/,用python写的话关键代码和状态转移方程形式基本一样。

思考

  • 动态规划为什么在解决一些问题上更加优秀?
    从直观上理解,动态规划方法在计算过程中进行了“记录”,从而避免了部分冗余计算。举个例子,计算 1 + 1 + ⋯ + 1 1+1+\cdots+1 1+1++1,如果使用顺序计算的策略,就会计算 1 + 1 , 1 + 1 + 1 , 1 + 1 + 1 , ⋯ 1+1,1+1+1,1+1+1,\cdots 1+1,1+1+1,1+1+1,,这个过程中进行了多次冗余计算。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值