
动态规划之简单(0-1)背包问题
动态规划之简单(0-1)背包问题
动态规划的经典题目
背包问题,今天尝试解答了一下,现总结如下。
题目描述
给你一个可装载重量为W的背包和N个物品,每个物品有重量和价值两个属性。其中第i个物品的重量为wt[i],价值为val[i],现在让你用这个背包装物品,最多能装的价值是多少?
举个简单的例子,输入如下:
1 | N = 3, W = 4 |
算法返回 6,选择前两件物品装进背包,总重量 3 小于W,可以获得最大价值 6。
解答
参考文章:https://labuladong.gitbook.io/algo/dong-tai-gui-hua-xi-lie/bei-bao-wen-ti
根据动态规矩的解题思路,首先应该明确三点:最优子结构、状态转移方程、重叠子问题。对于该题而言,状态为背包的重量,根据选择的物品的数量从而导致背包重量变化;对于每一个物品而言,每次有两个选择:装入背包、不转入背包,根据这一个特点可以总结出最优子结构为:max(‘装入背包’,’不转入背包’)。
这一步要结合对dp数组的定义和我们的算法逻辑来分析:
先重申一下刚才我们的dp数组的定义:
dp[i][w]表示:对于前i个物品,当前背包的容量为w时,这种情况下可以装下的最大价值是dp[i][w]。
如果你没有把这第i个物品装入背包,那么很显然,最大价值dp[i][w]应该等于dp[i-1][w]。你不装嘛,那就继承之前的结果。
如果你把这第i个物品装入了背包,那么dp[i][w]应该等于dp[i-1][w-wt[i-1]] + val[i-1]。
首先,由于i是从 1 开始的,所以对val和wt的取值是i-1。
而dp[i-1][w-wt[i-1]]也很好理解:你如果想装第i个物品,你怎么计算这时候的最大价值?换句话说,在装第i个物品的前提下,背包能装的最大价值是多少?
显然,你应该寻求剩余重量w-wt[i-1]限制下能装的最大价值,加上第i个物品的价值val[i-1],这就是装第i个物品的前提下,背包可以装的最大价值。
综上就是两种选择,我们都已经分析完毕,也就是写出来了状态转移方程,可以进一步细化代码:
1 | for i in [1..N]: |
具体代码:
1 | /** |




