算法题总结-完全背包问题
原题
https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c?tpId=37&tqId=21264&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3Fdifficulty%3D3%26page%3D1%26pageSize%3D50%26search%3D%26tpId%3D37%26type%3D37&difficulty=3&judgeStatus=undefined&tags=&title=
现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ;
每种砝码对应的数量为 x1,x2,x3...xn 。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
输入描述
对于每组测试数据:
第一行:n --- 砝码的种数(范围[1,10])
第二行:m1 m2 m3 ... mn --- 每种砝码的重量(范围[1,2000])
第三行:x1 x2 x3 .... xn --- 每种砝码对应的数量(范围[1,10])
输出描述
利用给定的砝码可以称出的不同的重量数
输入示例
2
1 2
2 1
输出示例
5
解析:
1、首先将数据进行分组,将问题转化为分组背包问题
完全背包源码[实际上如果数字比较大的时候会超时(因为volume) 20组用例仅能通过19例][该题目解答附在该源码之后]
import sys
N = 0
weight = []
num = []
count = 0
for line in sys.stdin:
a = line.split()
if count==0:
N = int(a[0])
elif count ==1:
weight = [int(item) for item in a]
elif count==2:
num = [int(item) for item in a]
else:
break
count+=1
# 所谓的砝码问题 如果将所谓的重量改成背包容量
# 即可将问题转化为完全背包问题
# print(N)
# print(weight)
# print(num)
strategy = []
maxVolume = 0
for i in range(len(weight)):
weightTmp = weight[i]
numTmp = num[i]
maxVolume+=weightTmp*numTmp
group = []
for j in range(1,numTmp+1):
group.append(weightTmp*j)
pass
strategy.append(group)
pass
# print(strategy)
# 至此已转化为01背包问题
# 转移方程 F[V] = max(F[V],F[V-Ci]+Wi)
F = [0 for i in range(maxVolume+1)]
for i in range(len(strategy)):
group = strategy[i]
for volume in range(maxVolume,0,-1):
for item in group:
volumeMinus = volume-item
if volumeMinus<0:
continue
try:
F[volume] = max(F[volume],F[volumeMinus]+item)
pass
except:
print("volume="+str(volume))
print("volumeMinus="+str(volumeMinus))
pass
pass
pass
pass
# print(F)
# print(set(F))
print(len(set(F)))
砝码解答源码:
1、仍然是分组
2、遍历每个分组,遍历已存数据,相加保存
3、最后去重即可得到所有组合结果数量
import sys
N = 0
weight = []
num = []
count = 0
for line in sys.stdin:
a = line.split()
if count==0:
N = int(a[0])
elif count ==1:
weight = [int(item) for item in a]
elif count==2:
num = [int(item) for item in a]
else:
break
count+=1
strategy = []
for i in range(len(weight)):
weightTmp = weight[i]
numTmp = num[i]
group = []
for j in range(1,numTmp+1):
group.append(weightTmp*j)
pass
strategy.append(group)
pass
allStrategy = [0]
for i in range(len(strategy)):
group = strategy[i]
strategySave = allStrategy.copy()
for j in range(len(strategySave)):
for item in group:
allStrategy.append(item+strategySave[j])
pass
allStrategy = list(set(allStrategy))
pass
print(len(set(allStrategy)))