题解 | #称砝码# 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;
    }
}

全部评论

相关推荐

09-28 17:38
门头沟学院 Java
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务