背包问题
有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。01背包是每件物品只能用一次;完全背包是每件物品数量无限。求解目标是将哪些物品装入背包里物品价值总和最大。
01背包问题-二维DP数组解法
遍历顺序的选择:只要正序遍历背包容量即可,遍历物品、背包容量的顺序可以颠倒
def test_2_wei_bag_problem1(weight, value, bagweight):
# dp[i][j]代表背包空间为j的情况下,从下标为0~i的物品里面任意取,能达到的最大价值
dp = [[0] * (bagweight + 1) for _ in range(len(weight))]
# 初始化
for j in range(weight[0], bagweight + 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])
return dp[len(weight) - 1][bagweight]
if __name__ == "__main__":
weight = [1, 3, 4]
value = [15, 20, 30]
bagweight = 4
result = test_2_wei_bag_problem1(weight, value, bagweight)
print(result)
01背包问题-一维DP数组解法
二维DP数组递归公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]),可以看出第i层可以由第i-1层得出
遍历顺序的选择:需要倒序遍历背包容量(为了保证每个物品只添加1次),且需要先遍历物品,再遍历背包容量
def test_1_wei_bag_problem(weight, value, bagWeight):
dp = [0] * (bagWeight + 1)
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])
return dp[bagWeight]
if __name__ == "__main__":
weight = [1, 3, 4]
value = [15, 20, 30]
bagweight = 4
result = test_1_wei_bag_problem(weight, value, bagweight)
print(result)
完全背包问题-一维DP数组解法
遍历顺序的选择:完全背包相对01背包,把倒序遍历背包容量改成正序遍历即可(为了保证每个物品可以添加多次)&#x