首先介绍一下背包问题的思路
定义数组dp[v]:对于一个体积为v的背包,dp[v]表示的是花费空间为v的最大解,0表示不能花费体积为v的空间
定义物品价值数组jz[n],jz[n]表示第n个物品的价值
定义物品体积数组tj[n],tj[n]表示第n个物品的体积
算法过程:
1.来一个物品,能放进背包就放进去,不能放进去直接丢掉
2.对于第一步不能丢的物品,判断它能否取代背包里已有的物品,如果能,则更新每一个使用到该物品的dp数组,设已使用空间为f(2)
3.对于第二步更新完的策略,原取代物品(或者是新来的物品)仍有可能可以继续放在背包内(只要不超过背包最大容量),可以组成新的方案,因此需要拓展方案,拓展范围是dp[0] - dp[f(2)],背包的使用空间从f(2)过渡到f(3)
4.继续放入物品,直到没有物品可以被选择,此时已经得到每一个体积v对应的最大价值,但是空间仍有可能有剩余,所以max(dp)是体积v能放下的最大价值,dp[-1]是刚好体积v的最大价值
n, v = (int(x) for x in input().split()) tj = [] jz = [] for i in range(n): t, j = (int(x) for x in input().split()) tj.append(t) jz.append(j) dp = [0 for i in range(v+1)] for i in range(n): # i表示向背包内放入第i个物体 if tj[i] > v: continue dp_copy = dp.copy() # 必须要拷贝数组,防止在原dp数组上重复累加 for j in range(v+1): # j表示背包体积 if dp[j] and j + tj[i] <= v: # 如果体积j有解并且能放下当前物品 dp_copy[j + tj[i]] = max(dp[j + tj[i]], dp[j] + jz[i]) # 更新物品放置策略(此时放进背包) dp_copy[tj[i]] = max(dp[tj[i]], jz[i]) # 更新体积tj[i]的解 dp = dp_copy # print(dp) print(max(dp)) print(dp[-1])