很多最优解问题都可以用动态规划来做,要想用动态规划来解决问题首先要满足的第一个条件就是问题能被分解,也就是能被分割成很多个小问题。
这一点相当重要,很多人一上来看了很多文章就提递推方程,绕的云里雾里的还是弄不清问题的本质,就是因为没理解这句话的真正含义,因为递推基础就是由小的子问题推导出总的大问题的解。所以分析一个问题的子问题是什么是第一步!
1.背包问题
背包问题的描述:有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
这是很经典的动态规划问题,如果你看过这个题目的解,肯定知道下面这个式子是解的核心:f[v]=max{f[v],f[v-c[i]]+w[i]} 。
这个式子怎么来的,崔添翼在他的背包九讲中说:我们可以理解为当前第 i 个物品的选择有两种:选或不选,那么对应的现在背包的价值就有f[v-c[i]]+w[i],和f[v]两种来源。
但是这个式子的来源也可以这么理解:原问题可以由其子问题进一步推导而来。
即求容量v的背包能获得的最大价值,那么他的子问题是不是可以看成:求容量v-1的背包能获得的最大价值呢?同理可以得到 v 个子问题:求容量为 v-2,v-3,·····的背包能获得的最大价值。我们设原问题:求容量v的背包能获得的最大价值 为问题pack,那么pack的最优解能否由pack的子问题的最优解进一步迭代推算出来呢?答案是肯定的。
对于pack最后的状态:即v耗尽,可以有N种来源:即最后放入背包内的是哪件物品。那么假设得到pack的最优解的时候放入的是物品n[i],那么在pack的最优解就变成了:背包容量为 v-c[i] 时,求解得到的最大价值+放入物品n[i]获得的价值。也就是说:f[v]=f[v-c[i]]+w[i]!