背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。
一般的,0-1背包问题可以描述为1个背包,物品的重量为wi,其价值为vi,背包容量为c。使其价值总量最大。即:
m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下:
以上是逆序,即从最满状态一个个扔。如下是顺序的递推式:
为节省空间,可以将二维的列表变为一维的,每次循环只需保留相应位置的较大值即可。
0-1背包问题又可以根据是否恰好放满背包,可以分为两类。首先第一类,就是只要价值最大,质量可以不是刚好最大;第二类则是质量刚好最大,而且价值最大。只需要设置不同的初始化条件,便可以实现不同的答案。
1.对于没有要求必须安装背包的情况下,初始化最大值都为0,是不存在非法状态的。因为可以什么都不装。2.但是如果要求恰好装满,则必须区别初始化,即f[0]=0,其他设为一个较大的负数。以下以例题进行讲解:
题目描述:
小白和小红一起逃亡,现在有许多的东西要放在小红的包里面,但是包的大小有限,所以我们只能够往里面放入非常重要的物品。现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样使背包的价值最大的组合方式,并输出这个值。
输入:
第一行有2个整数,物品种数n和背包装载体积v
第二行到i+1行每行3个整数,为第i种物品的数量m、体积w、价值s
输出:
一个整数,整数表示最大价值。
解析:
这题没有恰好,所以,初始化都为0即可,这里我用两种代码形式表示,一种是逆序的递推,一种顺序的递推:
代码实现:
1.逆序:
#-*-coding:utf-8 -*-
while True:
try:
n,v=map(int,raw_input().split())
we,se=[0],[0]
res=[]
t=[]
q=[]
r=0
for i in range(n):
m,w,s=map(int,raw_input().split())
r+=m
we.extend([w]*m)
se.extend([s]*m)
dp=[[0 for i in range(v+1)] for j in range(r+1)]
for j in range(v + 1):
if j >= we[r]:
dp[r][j] = se[r]
else:
dp[r][j] = 0
for i in range(r-1,-1,-1):
for j in range(v+1):
if j<we[i]:
dp[i][j]=dp[i+1][j]
else:
dp[i][j]=max(dp[i+1][j],dp[i+1][j-we[i]]+se[i])
print dp[0][-1]
except:
break
顺序:
def solve(v,w,s,n):
r = [0]*(s+1)
r[0]=0
for i in range(1,n+1):
for j in range(s,0,-1):
if w[i] <= j:
r[j] = max(r[j],r[j-w[i]]+v[i])
return r[-1]
if __name__ == '__main__':
n,weight=map(int,raw_input().split())
we=[0]
se=[0]
r=0
for i in range(n):
m, w, s = map(int, raw_input().split())
r += m
we.extend([w] * m)
se.extend([s] * m)
result = solve(se,we,weight,r)
print(result)
ps:这两个都在we和se数组最开始加了0,为了平衡数组的下标。
2.假如是恰好呢?
def solve2(v,w,s,n):
r = [-100]*(s+1)
r[0]=0
for i in range(1,n+1):
for j in range(s,0,-1):
if w[i] <= j:
r[j] = max(r[j],r[j-w[i]]+v[i])
return r[-1]
if __name__ == '__main__':
n,weight=map(int,raw_input().split())
we=[0]
se=[0]
r=0
for i in range(n):
m, w, s = map(int, raw_input().split())
r += m
we.extend([w] * m)
se.extend([s] * m)
result = solve2(se,we,weight,r)
print(result)
转载请注明:转自http://blog.csdn.net/carson0408/article/details/77825391