首页 > 试题广场 >

称砝码

[编程题]称砝码
  • 热度指数:209026 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}对于给定的 n 种砝码,重量互不相等,依次为 m_1, m_2, \dots, m_n ,数量依次为 x_1, x_2, \dots, x_n
\hspace{15pt}现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。特别地,称重重量包括 0

输入描述:
\hspace{15pt}第一行输入一个整数 n \left(1 \leqq n \leqq 10\right) 代表砝码的个数。
\hspace{15pt}第二行输入 n 个整数 m_1, m_2, \dots, m_n \left(1 \leqq m_i \leqq 2000\right) 代表每种砝码的重量。
\hspace{15pt}第三行输入 n 个整数 x_1, x_2, \dots, x_n \left(1 \leqq x_i \leqq 10\right) 代表每种砝码的数量。


输出描述:
\hspace{15pt}输出一个整数,代表利用给定的砝码可以称出的不同的重量数。
示例1

输入

2
1 2
2 1

输出

5

说明

\hspace{15pt}在这个样例中,有 2 个重量为 1 的砝码,1 个重量为 2 的砝码。称重方式如下:
\hspace{23pt}\bullet\,不放砝码,称重重量为 0
\hspace{23pt}\bullet\,1 个重量为 1 的砝码,称重重量为 1
\hspace{23pt}\bullet\,2 个重量为 1 的砝码,称重重量为 2
\hspace{23pt}\bullet\,1 个重量为 1 的砝码、1 个重量为 2 的砝码,称重重量为 3
\hspace{23pt}\bullet\,2 个重量为 1 的砝码、1 个重量为 2 的砝码,称重重量为 4
\hspace{15pt}因此,能称出的不同重量有 5 种,分别是 0, 1, 2, 3, 4

已老实,下述代码内存和时间不符合规范T T

n = int(input())
weight = list(map(int, input().split()))
numebr = list(map(int, input().split()))
ipt_dict = dict()
for w, num in zip(weight, numebr):
    ipt_dict[w] = num
res = set()
init_dict = dict()
for w in weight:
    init_dict[w] = 0
stack: list[dict] = []
stack.append(init_dict)
while stack:
    ## add to set
    top_dict = stack.pop()
    keys = list(top_dict.keys())
    # print(top_dict)
    res.add(sum([top_dict[key] * key for key in keys]))
    ## 砝码数量
    for key in weight:
        if top_dict[key] < ipt_dict[key]:
            new_dict = top_dict.copy()
            new_dict[key] += 1
            stack.append(new_dict)
print(len(res))y
发表于 2025-03-23 21:54:27 回复(0)
fm_type = int(input())

fm_num = [int(i) for i in input().split()]
fm_weight = [int(i) for i in input().split()]
list_val = [ fm_num[i] for i in range(fm_type) for j in range(fm_weight[i])]
list_val_tmp = {0,}
for i in list_val:
    for j in list(list_val_tmp):
        list_val_tmp.add(i+j)

print(len(set(list_val_tmp)))

发表于 2025-03-15 23:25:18 回复(0)
这题里python区大佬终于发力了,随手写的代码,就是小琴无法逾越的高山
n = int(input())
m = list(map(int,input().split()))
x = list(map(int,input().split()))
dp = 1
for i in range(n):
    for _ in range(x[i]):
        dp |= dp << m[i]
print(bin(dp).count("1"))

发表于 2025-01-15 22:48:14 回复(1)
将砝码个数和重量作为一个元组塞到一个列表内,然后从第一个砝码开始分别计算前边的重量可能性和当前重量可能性的笛卡尔积
PS:python真好用,啥方法都有 嘻嘻
import itertools

kind = int(input())
wei = input()
count = input()

dic = []

for i in range(kind):
    dic.append((wei.split()[i],count.split()[i]))

w1 = [0] * (kind + 1)
for i in dic:
    w2 = []
    for j in range(0,int(i[1])+1):
        z = j * int(i[0])
        w2.append(z)
    w1 = [x + y for x, y in itertools.product(w1, w2)]

p=[]
for i in w1:
    if i not in p:
        p.append(i)
print(len(p))

发表于 2025-01-08 14:14:16 回复(1)
kindNum=int(input())
line2=list(map(int,input().split()))
line3=list(map(int,input().split()))
famaList=list(zip(line2,line3)) #第一列是砝码重量,第二列是数量

##迭代函数
def get_sum2():
    result_arr=[]
    result_arr.append(0)
    for p in range(kindNum):
        result_arr=sorted(set(result_arr))
        this_result_num=len(result_arr)
        for q in range(1,famaList[p][1]+1):
            for r in range(this_result_num):
                result_arr.append(result_arr[r]+famaList[p][0]*q)
    return result_arr

print(len(sorted(set(get_sum2()))))

发表于 2024-12-15 13:01:34 回复(0)
# 输入砝码重量,砝码重量范围,砝码数量
types = int(input().strip())
weights = list(map(int, input().split()))
quantities = list(map(int, input().split()))

def weight_calculate(n, weights, quantities):
    # 跟踪所有可能的重量组合,从0开始
    possible_weights = {0}
   
    # 遍历所有可能的重量组合
    for i in range(n):
        current_weight = weights[i]
        current_quantity = quantities[i]
        # 初始化一个set用来储存每一轮遍历中发现的新的重量。
        new_weights = set()
       
        # 对于每一个储存在可能重量中的元素进行处理
        for existing_weight in possible_weights:
            # 从0到当前的砝码数量开始进行current_weight * quantity
            for q in range(1, current_quantity + 1):
                new_weight = existing_weight + q * current_weight
                new_weights.add(new_weight)
       
        # 使用每一轮新的重量来更新可能的重量组合
        possible_weights.update(new_weights)
   
    # 返回砝码数量
    return len(possible_weights)

# 打印结果
print(weight_calculate(types, weights, quantities))

发表于 2024-11-19 11:18:55 回复(0)
集合硬算
num_types = int(input())
weights = map(int, input().split())
nums = map(int, input().split())

possible_weights = {0}

for weight, num in zip(weights, nums):
    possible_weights = possible_weights | {
        possible_weight + weight * add_num
        for possible_weight in possible_weights
        for add_num in range(0, num + 1)
    }

print(len(possible_weights))


发表于 2024-09-24 20:47:55 回复(0)
该题实质是完全背包问题的一个变种,如果使用排列组合来找所有子集的方法时间复杂度高容易超时。
使用动态规划算法解决:
1. 定义状态:使用一个集合 possible_weights 来记录可能称出的所有重量。
2. 迭代每种砝码:对于每个砝码 m_i,在其对应的数量 x_i 之间进行迭代。   使用一个临时集合 new_weights 来保存当前迭代过程中产生的新重量。   对于现有的每个可能重量 w,添加 j * m_i(j 在 1 到 x_i 范围内),并将其添加到 new_weights 中。   最后,将 new_weights 中的所有重量添加到 possible_weights 中。
3. 计算所有可能重量:在完成所有砝码迭代后,possible_weights 应包含所有可能称出的重量。
4. 返回结果:possible_weights 的长度即为可能称出的不同重量数。  import sys


def count_possible_weights(n, weights, quantities):
    # 初始化可能称出的重量
    possible_weights = {0}  # 初始化为空重

    # 迭代每种砝码
    for i in range(n):
        current_weight = weights[i]
        current_quantity = quantities[i]
        # 新的可能重量集合
        new_weights = set()
        # 计算所有可能的重量
        for w in possible_weights:
            for j in range(1, current_quantity + 1):
                new_weight = w + j * current_weight
                new_weights.add(new_weight)
        # 合并到可能重量集合中
        possible_weights.update(new_weights)
    # 返回可能称出的不同重量数
    return len(possible_weights)


lines = []
for line in sys.stdin:
    line = line.strip()
    if line == "":
        break
    lines.append([int(i) for i in line.split(" ")])
for i in range(len(lines) // 3):
    n = lines[i][0]
    weights = lines[i + 1]
    quantities = lines[i + 2]
    print(count_possible_weights(n, weights, quantities))

发表于 2024-04-28 21:59:40 回复(0)
N = int(input())
m = [int(i) for i in input().split(' ') if i]
x = [int(i) for i in input().split(' ') if i]
mtype = {0} # 可称重重量统计,包括0
for i in range(N):
    for j in range(x[i]):
        mtype = {k+m[i] for k in mtype}.union(mtype)
print(len(mtype))

发表于 2024-04-20 19:11:41 回复(0)
def count_measurable_weights(n, weights, quantities):
    max_weight = sum(weight * quantity for weight, quantity in zip(weights, quantities))
    measurable_weights = set()
    measurable_weights.add(0)

    for weight, quantity in zip(weights, quantities):
        new_weights = set()
        for i in range(1, quantity + 1):
            for measurable_weight in measurable_weights:
                new_weights.add(measurable_weight + weight * i)
        measurable_weights.update(new_weights)

    return len(measurable_weights)

# Read input
n = int(input())
weights = list(map(int, input().split()))
quantities = list(map(int, input().split()))

# Calculate and print the result
result = count_measurable_weights(n, weights, quantities)
print(result)
1. 首先是函数定义:
   ```python
   def count_measurable_weights(n, weights, quantities):
   ```
   这里定义了一个名为`count_measurable_weights`的函数,它接受三个参数:
   - `n`:砝码的种类数
   - `weights`:一个列表,表示每种砝码的重量
   - `quantities`:一个列表,表示每种砝码的数量

2. 接下来计算最大可测量重量:
   ```python
   max_weight = sum(weight * quantity for weight, quantity in zip(weights, quantities))
   ```
   这行代码使用了Python的生成器表达式和`zip`函数:
   - `zip(weights, quantities)`将`weights`和`quantities`两个列表按照对应位置组合成元组
   - `weight * quantity for weight, quantity in zip(weights, quantities)`对每个元组中的重量和数量进行相乘
   - `sum(...)`对生成器表达式的结果求和,得到最大可测量重量

3. 初始化一个集合来存储可测量重量:
   ```python
   measurable_weights = set()
   measurable_weights.add(0)
   ```
   - 创建一个空集合`measurable_weights`来存储所有可测量的重量
   - 将0添加到集合中,因为不放置任何砝码时,重量为0

4. 遍历每种砝码:
   ```python
   for weight, quantity in zip(weights, quantities):
   ```
   再次使用`zip`函数将`weights`和`quantities`配对,遍历每种砝码的重量和数量

5. 对于每种砝码,计算它可以产生的新的可测量重量:
   ```python
   new_weights = set()
   for i in range(1, quantity + 1):
       for measurable_weight in measurable_weights:
           new_weights.add(measurable_weight + weight * i)
   ```
   - 创建一个空集合`new_weights`来存储新的可测量重量
   - 使用两个嵌套的循环:
     - 外层循环`for i in range(1, quantity + 1)`从1到当前砝码的数量进行遍历
     - 内层循环`for measurable_weight in measurable_weights`遍历当前已知的所有可测量重量
     - 对于每个已知可测量重量,加上当前砝码重量的1到`quantity`倍,得到新的可测量重量,并添加到`new_weights`集合中

6. 将新的可测量重量合并到原集合中:
   ```python
   measurable_weights.update(new_weights)
   ```
   使用`update`方法将`new_weights`集合中的元素添加到`measurable_weights`集合中

7. 返回可测量重量的总数:
   ```python
   return len(measurable_weights)
   ```
   使用`len`函数获取`measurable_weights`集合的大小,即可测量重量的总数

8. 读取输入:
   ```python
   n = int(input())
   weights = list(map(int, input().split()))
   quantities = list(map(int, input().split()))
   ```
   - 第一行输入`n`,表示砝码的种类数
   - 第二行输入`weights`,表示每种砝码的重量,使用空格分隔
   - 第三行输入`quantities`,表示每种砝码的数量,使用空格分隔
   - 使用`map`函数将输入的字符串转换为整数列表

9. 调用函数并输出结果:
   ```python
   result = count_measurable_weights(n, weights, quantities)
   print(result)
   ```
   - 调用`count_measurable_weights`函数,传入`n`, `weights`和`quantities`作为参数
   - 将返回的结果存储在`result`变量中
   - 使用`print`函数输出`result`,即可测量重量的总数
编辑于 2024-04-06 11:58:20 回复(0)
# 参考了大佬的代码,集合NB
n = int(input())
fama_weight = list(map(int,input().split()))
fama_num = list(map(int,input().split()))
sum = {0}
for i in range(n):
    jh = []
    for j in range(1,fama_num[i]+1):
        jh.append(fama_weight[i]*j)
    bf = sum.copy()
    for k in bf:
        for l in jh:
            sum.add(k+l)
print(len(sum))
编辑于 2024-02-11 08:43:17 回复(0)
    # 输入处理
    n = int(input())
    m =[int(i) for i in input().split()]
    x = [int(i) for i in input().split()]
    # 将所有砝码放到一个列表中
    lst = [m[i] for i in range(len(m)) for j in range(x[i])]

    #初始化(这里如果使用列表后面再set会超时报错)
    weight = {0,}
    #对每一个weight元素(已称出的重量),都加上新增的砝码重量并添加到weight中
    for i in lst:
        for j in list(weight):
            weight.add(j+ i)
    #输出
    print(len(weight))
编辑于 2023-12-23 22:34:34 回复(0)
n = int(input())
m = list(map(int, input().split()))
x = list(map(int, input().split()))
  
# 动态规划求解
# 方法一:利用二进制的位运算:|(或运算)
def count_different_weights1(n, weights, quantities):
    max_weight = sum(w * q for w, q in zip(weights, quantities))
    dp = 0
    dp |= 1  

    for w, q in zip(weights, quantities):
        for _ in range(q):
            dp |= dp << w
 
    return bin(dp).count("1")
  

# 方法二:利用经典动态规划,构建一个长为可能最大重量+1的数组
# 然后遍历每种砝码的每个砝码
# 再以递减顺序遍历dp的元素,判断满足该重量的条件是否存在
def count_different_weights2(n, weights, quantities):
    max_weight = sum(w * q for w, q in zip(weights, quantities))
    dp = [1] + [0]*max_weight

    for i in range(n):
        for _ in range(quantities[i]):
            for k in range(max_weight,weights[i]-1,-1):
                if dp[k-weights[i]]:
                    dp[k] = 1
    return sum(dp)

result = count_different_weights2(n, m, x)
print(result)
发表于 2023-10-18 09:48:45 回复(0)
砝码组递归:
def getWeightNum(m_arr,x_arr,pre_weight_map = {0:True},x = 0):
    weight_map = {}
    for pre_weight in pre_weight_map.keys():
        for i in range(x_arr[x]+1):
            weight_map[pre_weight + i*m_arr[x]] = True
    if(x == len(x_arr)-1): return len(weight_map)
    return getWeightNum(m_arr,x_arr,weight_map,x+1)


weight_num = int(input())
m_arr = list(map(int,input().split()))
x_arr = list(map(int,input().split()))

weight_map = {}
print(getWeightNum(m_arr,x_arr))


发表于 2023-07-21 16:43:21 回复(0)
n = int(input().strip())
kind_ls = list(map(int, input().strip().split()))
num_ls = list(map(int, input().strip().split()))

# 砝码列表 砝码种类、各类砝码数量 -> 砝码列表 
fama_ls = []
for i in range(n):
    for _ in range(num_ls[i]):
        fama_ls.append(kind_ls[i])

weights = {0}
# 每次取出一个砝码 与先前所有情形组合
for fama in fama_ls:
    weights |= {w + fama for w in weights}
print(len(weights))
        

发表于 2023-04-12 11:12:43 回复(1)
n = int(input())
m = list(map(int,input().split()))
x = list(map(int,input().split()))
mx = []#只放一个砝码时有多少种情况
for i in range(n):
    mx.extend([m[i]]*x[i])
weights = {0}#每次只加一个砝码上去记录下此时的重量
for i in mx:
#每次放入一个i和重量记录表各个值相加得到新的砝码组合重量,集合自动去重
    weights = weights.union({i+j for j in weights})
print(len(weights))


发表于 2023-02-25 14:58:43 回复(0)
参考讨论里一位用户的代码,使用集合和Counter类(学习了一下这个类,好方便)
from collections import Counter
n=int(input())
weight=list(map(int,input().strip().split(' ')))
num=list(map(int,input().strip().split(' ')))
w={0,}
c=Counter(dict(zip(weight,num)))
for i in c.elements():
    w.update(set(i+j for j in w))
print(len(w))


发表于 2023-02-21 19:20:07 回复(0)
n=int(input())
m=input().split()
x=input().split()
weight=[0]

for i in range(n):
    m[i]=int(m[i])
    x[i]=int(x[i])

for i in range(n):
    tmp_list=[m[i]*j for j in range(x[i]+1)]
    weight=list(set(a+b for a in tmp_list for b in weight))
print(len(weight))

发表于 2022-12-15 03:47:32 回复(1)