一、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])
#图形化参考网址:
二、完全背包问题
问题描述:
找零钱问题
使用一维数组进行解题
具体代码:
# coding = utf-8
def recDC(coinValueList, change, knownResults):
'''
找零问题
:param coinValueList: 已有零钱的数值
:param change: 需要找的零钱总数
:param knownResults: 查询表--存储某个找零金额对应的最少硬币数
:return: 最少硬币数
'''
minCoins = change
if change in coinValueList:
knownResults[change] = 1
return 1
#检查查询表中是否已经有某个找零金额对应的最少硬币数。如果没有,就递归地计算并且把得到的最少硬币数结果存在表中。
elif knownResults[change] > 0:
return knownResults[change]
else:
for i in [c for c in coinValueList if c <= change]:
numCoins = 1 + recDC(coinValueList, change - i, knownResults)
if numCoins < minCoins:
minCoins = numCoins
knownResults[change] = minCoins
return minCoins
a =recDC([1, 5, 10, 25], 63, [0] * 100)
print(a)