n,m = tuple(map(int,input().split()))
bag = []
for _ in range(n):
bag.append(tuple(map(int,input().split())))
history = {}
def f(i,j):
global history
a,b = bag[i-1]
if (i,j) in history.keys():
return history[(i,j)]
if i==1:
if a>j:
history[(i, j)]=0
return 0
else:
history[(i, j)]=b
return b
if j<a:
history[(i, j)]=f(i-1,j)
return history[(i, j)]
else:
history[(i, j)]=max(f(i-1,j) , f(i-1,j-a)+b)
return history[(i, j)]
print(f(n,m))
算法中最基础的题目之一。大意就是,一定容积的背包,向其中装入一定量的物品——每个物品有特定的体积和价值——使得背包中物品总价值最大。在此题情境中,每个物品只能放进去一次。
题目输入较为简单,第一行是物品总件数和背包容积;之后若干行是某件物品的体积和价值。
本题的方法是,对于数组i,j,定义函数:前 i 件物品中选择若干物品,体积不超过 j 的最大价值。
题目需要递归,通过比较有第 t 件物品和没有第 t 件物品时,最大总价值,来判断是否需要将第 t 件物品放入“背包”。注意到,前者可由函数(i-1 , j)表示出来;后者则需(i-1 , j-v(t))+w(t)来表示。由此,一直递归到 t = 1 ,即可得出结果。(t = 1 时,若第1件物品大于总体积,则不放入;反之放入——需要特殊处理)
本人所写上部python代码尚有问题,即会陷入死循环。应该与边界处理不善有关。不过我想了个办法——名为history的字典,若(i , j)的函数已经计算过,则不再计算,直接返回结果。实测有效。这也进一步验证了代码中存在问题的部分,未来需要解决。
1214

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



