题解 | #称砝码# DP
称砝码
https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c
import java.util.Scanner;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入砝码种类数
int n = scanner.nextInt();
// 输入每种砝码的重量
int[] weights = new int[n];
for (int i = 0; i < n; i++) {
weights[i] = scanner.nextInt();
}
// 输入每种砝码的数量
int[] counts = new int[n];
for (int i = 0; i < n; i++) {
counts[i] = scanner.nextInt();
}
// 调用函数计算能称出的不同重量数
int result = calculateDistinctWeights(n, weights, counts);
System.out.println(result);
}
public static int calculateDistinctWeights(int n, int[] weights, int[] counts) {
// 计算最大可能的重量(即每种砝码都用最大数量的和)
int maxWeight = 0;
for (int i = 0; i < n; i++) {
maxWeight += weights[i] * counts[i];
}
// dp数组,dp[i]表示重量i是否可以称出
boolean[] dp = new boolean[maxWeight + 1];
dp[0] = true; // 初始条件:可以称出重量0
// 动态规划更新dp数组
for (int i = 0; i < n; i++) {
int weight = weights[i];
int count = counts[i];
// 从后往前遍历,避免重复使用同一种砝码
for (int j = maxWeight; j >= 0; j--) {
// 逐个添加不同数量的该砝码
if (dp[j]) {
for (int k = 1; k <= count; k++) {
if (j + k * weight <= maxWeight) {
dp[j + k * weight] = true;
} else {
break;
}
}
}
}
}
// 统计能称出的不同重量数
int distinctWeightCount = 0;
for (boolean canWeigh : dp) {
if (canWeigh) {
distinctWeightCount++;
}
}
return distinctWeightCount;
}
}
查看3道真题和解析