目录
概念
步骤
数组转化
遍历顺序
代码编写
概念
W:背包最大总重量
Y:当前最大总重量限制(遍历时会变动:0~W)
N:物品的总数量
w_j:物品 j 的重量(j=0~N)
p_j:物品 j 的价值
A(j, Y):总重量不超过Y的前提下,前 j 个物品的最高价值
步骤
单重+单价\总重Y | 0 | 1 | 5 | 9 |
0,0 | ||||
1,2 | ||||
4,3 | ||||
5,4 |
对于j=0,A(0, Y) = 0;
对于Y=0,A(Y,0) = 0。
单重+单价\总重Y | 0 | 1 | 5 | 9 |
0,0 | 0 | 0 | 0 | 0 |
2,2 | 0 | |||
4,3 | 0 | |||
5,4 | 0 |
对于j=1,wj=2,pj=2,Y=1时,有wj > Y,因此放不下,所以沿用前(j-1)个时的价值,而Y不变。
单重+单价\总重Y | 0 | 1 | 5 | 9 |
0,0 | 0 | 0 | 0 | 0 |
2,2 | 0 | 0 | ||
4,3 | 0 | |||
5,4 | 0 |
有可能放入后的总价值,还不如不放入的高。
比如:总重量5,已经放入了(4,5),现在要放进去(2,1),挤出去(2,2),那总重量更新为(4,4),总价值变得更小了。
0560,00002,302,32,204,52,104,4??
对于j=1,wj=2,pj=2,Y=5时,有wj < Y,因此可以放下。
A(j-1,Y):不放入当前物品时的最大价值。
A(j-1,Y-wj):对于前j-1个物品,最大值重量为Y-wj时,看它能存的最大总价值是多少。
pj+A(j-1,Y-wj):即先看去掉当前物品重量后,能存的最大价值,再加上当前物品的价值。
单重+单价\总重Y | 0 | 1 | 5 | 9 |
0,0 | 0 | 0 | 0 | 0 |
2,2 | 0 | 0 | 2,2 | 2,2 |
4,3 | 0 | 0 | 4,3 | 6,5 |
5,4 | 0 | 0 | 5,4 | 9,7 |
数组转化
前 i 个物品,在最大重量限制为 j 的情况下,最大价值为 dp[i][j]。
- 由于存在0行和0列,因此长度需要额外+1。
- 重量长度 = 背包总重+1。
- 物品长度 = 物品总数+1。
- 根据递推公式,当前 dp[i][j] 由上方或左上角的内容,推算而来。
- 最后结果只需要返回dp右下角的值即可。
遍历顺序
两层for循环:
- 第一层(外层):遍历物品
- 第二层(内层):遍历背包
- 备注:对于当前的二维数组,顺序可颠倒。