import java.util.HashSet;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] m = new int[n]; // 砝码重量
        int[] x = new int[n]; // 砝码数量

        for (int i = 0; i < n; i++) {
            m[i] = sc.nextInt();
        }
        for (int i = 0; i < n; i++) {
            x[i] = sc.nextInt();
        }

        // 使用 HashSet 存储所有可能的重量
        HashSet<Integer> possibleWeights = new HashSet<>();
        possibleWeights.add(0); // 初始状态:不放砝码,重量为 0

        for (int i = 0; i < n; i++) { // 遍历每种砝码
            HashSet<Integer> temp = new HashSet<>(possibleWeights); // 避免遍历时修改
            for (int weight : temp) { // 遍历当前所有可能的重量
                for (int k = 1; k <= x[i]; k++) { // 尝试放 1 到 x[i] 个当前砝码
                    possibleWeights.add(weight + k * m[i]);
                }
            }
        }

        System.out.println(possibleWeights.size());
    }
}

动态规划(DP)解法思路

这道题可以用 动态规划(DP) 来解决,思路如下:

  1. 定义状态:dp[i] 表示是否能称出重量 i,true 表示可以,false 表示不可以。
  2. 初始化:dp[0] = true(因为不放砝码时,重量为 0)。
  3. 状态转移:遍历每种砝码 m_i,并遍历其数量 x_i。对于每一个可能的重量 j(从当前最大可能重量向下遍历,避免重复计算),如果能称出 j,那么加上 k 个 m_i 也能称出 j + k * m_i。
  4. 统计结果:最终 dp 数组中 true 的个数即为能称出的不同重量数。