算法题总结-完全背包问题

原题
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)))
posted @ 2023-06-14 23:22  356a  阅读(52)  评论(0编辑  收藏  举报