文章目录
- 题目描述
- 题解思路
- 题解代码
题目描述
题解思路
完全背包问题和01背包问题不同的地方就是完全背包问题中每个物品能选无数次,而01背包问题中每个物品最多只能选择一次
如果你还没有学过01背包,请先看这篇博客学习01背包:https://blog.csdn.net/qq_67733273/article/details/143066295
其实代码其实也很简单,我们只需要在01背包问题代码的基础上,把遍历背包容量改为正序遍历这种方式即可
这是因为我们每个物品能够被选无数次,我们在遍历容量过程中需要让前面遍历容量的结果影响到当前容量的结果,也就是我们可以基于选择过某个物品后获得的某个容量下的最大值可以用来求更大背包容量下也选择该物品的最大值,即可以选择已经选择过当前物品的容量的最大价值来尝试刷新当前容量下的最大价值
题解代码
# N:物品数量,V:背包容量
N, V = map(int, input().split(' '))
# vs[i]:第i个物品的体积,ws[i]:第i个物品的价值
vs, ws = [], []
for i in range(N):
a, b = map(int, input().split(' '))
vs.append(a)
ws.append(b)
# 选第i个之前的物品,放入容量为j的背包,最大价值
f = [0] * (V + 1)
# 状态转换方程:f[j] = max(f[j], f[j - vs[i]] + ws[i])
for i in range(N):
# 遍历物品
v, w = vs[i], ws[i]
for j in range(v, V + 1):
# 遍历容量充足的背包,并且其中f[j - v]是尝试选择当前物品无数次后获取的最大值,即我们可以选择已经选择过当前物品的容量的最大价值来获取当前容量的最大价值
f[j] = max(f[j], f[j - v] + w)
print(f[-1])