1. 问题背景与需求分析
这道来自华为机考的"称砝码"问题,表面看似简单,实则考察了多重编程思维。题目通常给出n种不同重量的砝码各若干枚,要求计算出用这些砝码能称出多少种不同的重量组合。这类问题在实际场景中广泛存在于物流称重、实验室测量、工业生产等领域。
举个例子,假设有1g和2g两种砝码,数量分别为2个和1个,那么可以组合出:0g(不放砝码)、1g、2g(1+1或单个2)、3g(1+2)、4g(1+1+2)共5种重量。这就是我们需要通过程序实现的组合计算。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法解析
2.1 动态规划解决方案
这类组合问题最适合采用动态规划(DP)来解决。DP的核心思想是将大问题分解为小问题,通过解决小问题来构建大问题的解。
我们定义一个布尔型数组dp,其中dp[i]表示重量i是否可以被称出。初始化时dp[0]=true(表示0重量总是可达),其余为false。然后遍历每种砝码,更新dp数组。
python复制def count_weights(weights, counts):
total = sum(w*c for w,c in zip(weights, counts))
dp = [False]*(total+1)
dp[0] = True
for w, c in zip(weights, counts):
for i in range(total, -1, -1):
if dp[i]:
for k in range(1, c+1):
if i + w*k <= total:
dp[i + w*k] = True
return sum(dp)
2.2 算法优化思路
上述基础实现有三个关键优化点:
- 逆向遍历重量范围,避免同一砝码被重复计算
- 提前计算最大可能重量,减少无效计算
- 使用集合代替数组可以节省空间,但可能略微降低速度
3. 完整实现与测试
3.1 Python实现代码
python复制def solve():
n = int(input())
