一、01背包问题(经典)
问题描述:
有N件物品和⼀个最多能被重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能⽤⼀次,求解将哪些物品装⼊背包⾥物品价值总和最⼤。
输入描述:
##### 初始化参数
#### 物品数量
count = 3
#### 背包最大 4
max_weight = 4
#### 价值
value = [15,20,30]
#### 重量
weight = [1,3,4]
输出描述:
35
思路:
思考第i件物品时,最大价值为max(不能取第i间物品的最大价值,能取第i件物品且剩余空间能装前i-1件物品的最大价值)
递推公式 dp[i][j] = dp[i-1][j]dp[i][j] = dp[i-1][j-weight[i]]+value[i]
由dp[i - 1][j]推出,即背包容量为j,⾥⾯不放物品i的最⼤价值,此时dp[i][j]就是dp[i - 1][j]
由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-weight[i]]+value[i],dp[i-1][j])
参考:蓝桥杯专辑(Python组)——0-1背包问题_蓝桥杯求解01背包问题python-CSDN博客
B站【DP动态规划】备战蓝桥杯——DP算法模板超详细讲解
具象化描述参考:
B站【自制】01背包问题算法动画讲解
两个B站视频之间的联系与区别:首先来说就是说思路是完全一样的,只是在dp数组行数代表的物品数时,讲解算法的物品从0,1,2开始,即物品0,物品1,物品2,但是在背包动画演示的视频中物品是从1开始计数,即物品1,物品2,物品3,所以在代码实现上有一些细微的区别。
具体代码:
采取的是物品从0开始计数的方式
# coding = utf-8
# 初始化数量
count = 3
# 背包最大容量
max_weight = 4
# 物品价值
value = [15, 20, 30]
# 物品重量
weight = [1, 3, 4]
# 构建dp数组
dp = [[0 for i in range(max_weight + 1)] for j in range(count)]
# 初始化dp数组的第一列和第一行
for i in range(1):for j in range(max_weight + 1):if weight[i] <= j:dp[i][j] = value[i]
# 迭代形式
for i in range(1, count):for j in range(1, max_weight + 1):# 取该物品时if j >= weight[i]:dp[i][j] = max(dp[i - 1][j - weight[i]] + value[i], dp[i - 1][j])# 不取该物品时else:dp[i][j] = dp[i - 1][j]
# 输出最后结果
print(dp[count - 1][max_weight])#图形化参考网址: