0-1背包是典型的动态规划问题,同时也是秋招笔试和面试常考问题,所以必须解决,其他公众号或者博客都写到,解决动态规划问题,要遵循以下步骤进行考虑:
1、明确dp数组的下标含义
2、确定递推公式
3、dp数组初始化
4、遍历序列
5、打印dp数组
我们可以先假设一个例子:
背包的最大重量为 4
物品为:
| |重量 | 价值
|物品0| 1 | 15
|物品1| 3 | 20
|物品2| 4 | 30
第一步,明确dp数组的下标含义,使用二维数组dp[i][j], 即dp[i][j] 表示从下标为[0-i]的物品⾥任意取,放进容量为j的背包,价值总和最⼤是多少。一定要明确dp数组的下标含义,要不以后会越来越蒙圈, 建议可以画一个如下的表格

第二步 确定递推公式
可以有两个⽅向推出来dp[i][j],明确任务这个物品放不放到背包之中
(1)如果物品 不满足条件 既物品不放到背包中。 由dp[i - 1][j]推出,即背包容量为j,⾥⾯不放物品i的最⼤价值,此时dp[i][j]就是dp[i - 1][j]
(2)物品要放到背包中,由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最⼤价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最⼤价值
所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
第三步:dp数组初始化
1、如果背包的重量为0, 则任何物品都放不到背包中

2、由递推公式可知,dp[i][j] 都是由dp[i-1]推导而来,所以需要明确dp[i-1]的值,既需要先定义表格中第一行的数据,也就是物品0放入背包中的value.

python代码如下:
dp = [[0] * (bagweight+1) for i in range(len(weight))]
for j in range(weight[0],bagweight+1, 1):
dp[0][j] = value[0]
第四步,遍历顺序
由dp数组肯定双循环,可以先遍历物品,然后遍历背包, 也可以先遍历背包,然后物品。我是按照先遍历物品,然后背包的顺序:
for i in range(1, len(weight)):
for j in range(bagweight+1):
if (j < weight[i]): dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + value[i])
第五步 打印dp数组
可以按照上一步的递推顺序,把数据依次填入上面的表格中,加深理解

python完整代码如下:
#物品重量和价值
weight = [1, 3, 4]
value = [15, 20, 30]
#背包重量
bagweight = 4
#初始DP数组
dp = [[0] * (bagweight+1) for i in range(len(weight))]
for j in range(weight[0],bagweight+1, 1):
dp[0][j] = value[0]
#开始循环
for i in range(1, len(weight)):
for j in range(bagweight+1):
if (j < weight[i]): dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + value[i])
#打印结果
print(dp[len(weight) - 1][bagweight])
Python补充代码,使用一维数组(滚动数组):
weight = [1, 3, 4]
value = [15, 20, 30]
bagweight = 4
#初始DP数组
dp = [0 for i in range(bagweight+1)]
#开始循环(注意下面这俩for循环不能颠倒,不信自己试试看)
for i in range(len(weight)):
for j in range(bagweight, weight[i] -1, -1):
dp[j] = max(dp[j], dp[j-weight[i]] + value[i])
print(dp[bagweight])
本文详细介绍了如何使用动态规划解决0-1背包问题,包括明确dp数组的含义、确定递推公式、初始化dp数组、遍历操作及打印结果。通过一个具体的例子,解释了动态规划在背包问题中的应用,最后给出了Python代码实现,包括一维数组的滚动优化版本。
4万+

被折叠的 条评论
为什么被折叠?



