1、背包问题
动态规划先解决子问题,再逐步解决大问题。每个动态规划都从一个网格开始,背包问题的网格如下:
网格最初是空的,动态规划就是逐步将网格填满。
吉他行
第一个单元格表示背包的容量为1磅。 吉他的重量也是1磅, 这意味着它能装入背包! 因此这个单元格包含吉他, 价值为1500美元。 来看下一个单元格,这个单元格表示背包的容量为2磅, 完全能够装下吉他!这行的其他的单元格也是如此,因为你目前只能把吉他装入背包,其他两种商品还未出现,所以第一行变成下图:
注意:这行表示的是当前的最大价值。
音响行
现在来到第二行,在每一行,可偷的商品都是当前行的商品和之前各行的商品。因此,当前你已经解锁了音响和吉他,但是笔记本电脑还未解锁。现在来看第一个单元格,它表示容量为1磅的背包。 在此之前, 可装入1磅背包的商品的最大价值为1500美元。 背包的容量为1磅, 能装下音响吗? 音响太重了, 装不下! 由于容量1磅的背包装不下音响, 因此最大价值依然是1500美元。 接下来的两个单元格的情况与此相同。
现在来到了第四个单元格,也就是说背包容量为4磅,终于能装下音响,由于音响的价值为3000美元,比1500美元的吉他值钱多了,所以还是偷音响吧。
笔记本电脑行
下面以同样的方式处理笔记本电脑。 笔记本电脑重3磅, 没法将其装入容量为1磅或2磅的背包, 因此前两个单元格的最大价值还是1500美元。
对于容量为3磅的背包, 原来的最大价值为1500美元, 但现在你可选择盗窃价值2000美元的笔记本电脑而不是吉他, 这样新的最大价值将为2000美元!
现在来到这个问题最关键的单元格,对于容量为4磅的背包,当前的最大价值为3000美元, 你可不偷音响, 而偷笔记本电脑, 但它只值2000美元。但是笔记本电脑的重量只有3磅, 背包还有1磅的容量没用! 在1磅的容量中, 可装入的商品的最大价值之前计算过。根据之前计算的最大价值可知, 在1磅的容量中可装入吉他, 价值1500美元。于是有了下面的比较:
于是我们得到了最终的结果:
在这个过程中,我们填入单元格时用到了下面的公式:
2、背包问题FAQ
- 沿着一列往下走时, 最大价值有可能降低吗?
- 行的排列顺序发生变化时结果将如何变化?
答案:没有变化。 也就是说, 各行的排列顺序无关紧要。
- 可以逐列而不是逐行填充网格吗?
答案:就这个问题而言, 这没有任何影响, 但对于其他问题, 可能有影响。
- 增加一件更小的商品将如何呢?
答案:单元格的按最小商品的重量划分。
- 可以偷商品的一部分吗?
答案:没法处理。 使用动态规划时, 要么考虑拿走整件商品, 要么考虑不拿, 而没法判断该不该拿走商品的一部分。
但使用贪婪算法可轻松地处理这种情况! 首先, 尽可能多地拿价值最高的商品; 如果拿光了, 再尽可能多地拿价值次高的商品, 以此类推。
- 动态规划可以处理相互依赖的情况吗?
- 计算最终的解时会涉及两个以上的子背包吗?
答案:根据动态规划算法的设计, 最多只需合并两个子背包, 即根本不会涉及两个以上的子背包。 不过这些子背包可能又包含子背包。
- 最优解可能导致背包没装满吗?
答案:完全可能。
3、动态规划的启发
- 动态规划可帮助你在给定约束条件下找到最优解。 在背包问题中,你必须在背包容量给定的情况下, 偷到价值最高的商品。
- 在问题可分解为彼此独立且离散的子问题时, 就可使用动态规划来解决。
- 每种动态规划解决方案都涉及网格。
- 单元格中的值通常就是你要优化的值。 在前面的背包问题中, 单元格的值为商品的价值。
- 每个单元格都是一个子问题, 因此你应考虑如何将问题分成子问题, 这有助于你找出网格的坐标轴。
4、小结
- 需要在给定约束条件下优化某种指标时, 动态规划很有用。
- 问题可分解为离散子问题时, 可使用动态规划来解决。
- 每种动态规划解决方案都涉及网格。
- 单元格中的值通常就是你要优化的值。
- 每个单元格都是一个子问题, 因此你需要考虑如何将问题分解为子问题。
- 没有放之四海皆准的计算动态规划解决方案的公式。
5、练习
- 假设你还可偷另外一件商品——MP3播放器, 它重1磅, 价值1000美元。 你要偷吗?
- 假设你要去野营。 你有一个容量为6磅的背包, 需要决定该携带下面的哪些东西。 其中每样东西都有相应的价值, 价值越大意味着越重要:
书(重 1 磅, 价值 3 )
食物(重 2 磅, 价值 9 ) ;
夹克(重 2 磅, 价值 5 ) ;
相机(重 1 磅, 价值 6 ) 。
请问携带哪些东西时价值最高?
你应携带水、 食物和相机。
- 请绘制并填充用来计算blue和clues最长公共子串的网格。