算法思想说明
0-1背包问题是说有一个背包,若干物品,背包有一定的容量,这些物品有自己的重量和价值,求如何放能使背包里物品的总价值最大,每件物品只能选择放或不放。 用递归的思想来解决0-1背包问题,为了减少递归次数,加入记忆算法,使得代码效率更高。
代码
n = 3; c = 5 #n个物品,背包容量为c
w = [0,1,2,3] #物品重量
v = [0,2,4,3] #物品价值
def ks(n,c):
if memo[n][c] != 0:
return memo[n][c]
if n==0 or c==0:
result = 0 # 意味着没有物品可选或承重为0,因此最大价值为0
elif w[n]>c:
result = ks(n-1,c)
else:
t1 = ks(n-1,c)
t2 = v[n] + ks(n-1,c-w[n])
result = max(t1,t2)
memo[n][c] = result
return result
memo = [[0]*(c+1) for x in range(n+1)] #存结果,减少递归次数
res = ks(n,c)
print(res)
例题
编程实现:
期末考试小明取得了优异的成绩、妈妈为鼓励小明再接再厉、在网购平台指定了N(2<=N<=50)件礼物供小明挑选,挑选前妈妈提出了以下要求:
1)每种礼物只能挑造1件;
2)所挑选的物品总价格不能大于V(1<=V<=100)
已知N件礼物中每件礼物的价格和小明对每件礼物的喜爱值(喜爱值越大喜爱程度越高),请你帮助小明挑选礼物,使得挑选的礼物在满足要求的前提下,总的喜爱值最大,并输出最大喜爱值。
输入描述
第一行输入两个正整数N(2<=N<=50)和V(1<=V<=100),分别表示指定的礼物数量和所挑选的礼物总价格不能大于的值,正整数之间以一个英文逗号隔开
第二行开始,输人N行,每行输入两个正整数J(1<=J<=V)和K(1<=K<=100),分别表示每件礼物的价格和喜爱值,正整数之间以一个英文逗号隔开
输出描述
输出一个整数,表示在满足题目要求下的最大喜爱值
样例输入
3,5
1,2
2,4
3,3
样例输出
7
例题分析
比较经典的一道0-1背包问题,我们直接迁移以上代码,稍做修改即可。
代码解决例题
n,c = map(int, input().split(','))
w = [0]; v = [0]
for i in range(0, n):
wi,vi = map(int, input().split(','))
w.append(wi); v.append(vi)
def ks(n,c):
if memo[n][c] != 0:
return memo[n][c]
if n==0 or c==0:
result = 0 # 意味着没有物品可选或承重为0,因此最大价值为0
elif w[n]>c:
result = ks(n-1,c)
else:
t1 = ks(n-1,c)
t2 = v[n] + ks(n-1,c-w[n])
result = max(t1,t2)
memo[n][c] = result
return result
memo = [[0]*(c+1) for x in range(n+1)] #存结果,减少递归次数
res = ks(n,c)
print(res)