问题描述:
现有n件物品和一个容量为c的背包。第i件物品的重量是重量为w[i],价值是v[i]。已知对于一件物品必须选择取(用1表示)或者不取(用0表示),且每件物品只能被取一次(这就是“0-1”的含义)。求放置哪些物品进背包,可使这些物品的重量总和不超过背包容量,且价值总和最大。
求解思路:
![](https://i-blog.csdnimg.cn/blog_migrate/9dbf09933e9b55989c8261f7cb85e46b.png)
m[i][j]表示当可以放入前i件物品且背包容量为j时的最大价值。当只能放入第一件物品即i=0时:若背包容量j<w[0],物品不能够被放入背包;若j>=w[0]时,物品可以放入背包,此时m[0][j]=v[0]。当可以放入前2件物品即i=1时,我们需要进行这样的处理:若j<w[1]时,说明第2件物品不能被放入背包内,此时背包的最大价值为背包中只放入第一件物品的最大价值,即m[1][j]=m[0][j];若j>=w[1]时,假设此时背包容量j=8,第二件物品可以被放入背包内,那么便会出现两种情况:
(1)将第二件物品放入背包,那么背包中物品的最大价值是多少呢?因为第二件物品重量为w[1]=2,在将第二件物品放入背包之前,背包的容量应为j-w[1]=8-2=6,此时背包的最大价值是m[0][6],因此若将第二件物品放入背包,其背包的最大价值m[1][j]=m[0][j-w[1]]+v[1];
(2)不将第二件物品放入背包,那么此时背包中物品的最大价值依然为只放入第一件物品时背包的最大价值,即m[1][j]=m[0][j];
我们选取(1)(2)中价值的较大者作为i=1,j=8时背包中的最大价值。
i=2,3,4时的分析同上,直到背包的容量为10,此时m[4][10]即为背包中物品的最大价值。
有了上面的分析,我们很容易写出下面的递归关系:
(1)i=0 当j<w[0]时,m[0][j]=0;当j>=w[0]时,m[0][j]=v[0]。
(2)i>0 当j<w[i],m[i][j]=m[i-1][j];当j>=w[i],m[i][j]=max{m[i-1][j-w[i]]+v[i],m[i-1][j]}。
w=[2,2,6,5,4] #物品重量
v=[6,3,5,4,6] #物品价值
c=10 #背包容量
n=len(w)
m=[[-1 for j in range(c+1)] for i in range(5+1)]
for j in range(c+1):
if j>=w[0]:
m[0][j]=v[0]
for i in range(1,n):
for j in range(1,c+1):
if j<w[i]:
m[i][j]=m[i-1][j]#不装入背包
else:
if (m[i-1][j-w[i]]+v[i]>m[i-1][j]):
m[i][j]=m[i-1][j-w[i]]+v[i]
else:
m[i][j]=m[i-1][j]
print(m[n-1][c])