初识动态规划
初识动态规划
初识动态规划
动态规划比较适合用来求解最优问题,比如求最大值、最小值等等。它可以非常显著地降低时间复杂度,提高代码的执行效率。
下面介绍来两个实例
实例
0-1 背包问题
背包最大承重为9,每个物品的重量分别是 2,2,4,6,3
回溯算法的递归树表示
从递归树中,你应该能会发现,有些子问题的求解是重复的,比如图中 f(2, 2) 和 f(3,4) 都被重复计算了两次。当然,我们可以借助 备忘录 来记录状态。
但是,我们还可以用动态规划来处理这个问题。
我们把整个求解过程分为 n 个阶段,每个阶段会决策一个物品是否放到背包中。每个物品决策(放入或者不放入背包)完之后,背包中的物品的重量会有多种情况,也就是说,会达到多种不同的状态,对应到递归树中,就是有很多不同的节点。
由此推出动态规划解决问题的思路:
我们把问题分解为多个阶段,每个阶段对应一个决策。我们记录每一个阶段可达的状态集合(去掉重复的),然后通过当前阶段的状态集合,来推导下一个阶段的状态集合,动态地往前推进。
0-1 背包问题升级版
在原来的基础上加入物品价值的概念,分别为3,4,8,9,6
在满足背包最大重量限制的前提下,背包中可装入物品的总价值最大是多少呢?
先来看递归树
我们用一个二维数组 states[n][w+1],来记录每层可以达到的不同状态。不过这里数组存储的值不再是 boolean 类型的了,而是当前状态对应的最大总价值。我们把每一层中 (i, cw) 重复的状态(节点)合并,只记录 cv 值最大的那个状态,然后基于这些状态来推导下一层的状态。
时间复杂度 O(n*w)
空间复杂度 O(n*w)
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!