青训营字节 MarsCode 技术训练营第六课——题解 | 豆包MarsCode AI 刷题

62 阅读2分钟

题目链接:

251巧克力板选择问题:巧克力板选择问题 - MarsCode

题目大意:

小M在春游时打算携带尽可能多的巧克力板。她拥有n块巧克力板,每块巧克力的边长为aiai​,重量为ai*ai。小M有多个不同大小的背包,每个背包都有一定的最大承重限制。她希望你帮助她计算在每个背包的最大承重范围内,最多可以带走多少块巧克力板。

例如:小M有5块巧克力板,边长分别为1, 2, 2, 4, 5,有5个不同的背包,其最大承重分别为1, 3, 7, 9, 15。对于每个背包,她能装入的巧克力块数分别是1, 1, 2, 3, 3

这道题可以通过贪心算法实现,贪心算法是在每一步选择中都采取在当前状态下最优的选择,从而希望最终得到全局最优解。贪心算法还具有最优子结构,即问题的最优解包含他的子问题的最优解。

对于这道题,我们可以每次选择当前最轻的巧克力板装入背包,这样可以最大化地利用背包的承重能力。

具体实现

  1. 存储重量的数组及排序:
        int[] weights = new int[n];
        for (int i = 0; i < n; i++) {
            weights[i] = a[i] * a[i];
        }

        Arrays.sort(weights);

题目中只给出了每块巧克力的边长,我们构造一个数组来存储重量

  1. 每个背包存储的巧克力板数量
        int[] result = new int[m];

3.贪心算法实现

        for (int i = 0; i < m; i++) {
            int maxWeight = queries[i];
            int count = 0;
            int currentWeight = 0;

            for (int j = 0; j < n; j++) {
                if (currentWeight + weights[j] <= maxWeight) {
                    currentWeight += weights[j];
                    count++;
                } else {
                    break;
                }
            }

            result[i] = count;
        }

对于每个背包,首先初始化最大称重量、巧克力板数量、当前承重。

在写代码时,参考示例时发现题目的意思时有五种不同类型的巧克力板,而不是五个背包一共五块不同的巧克力板,对于每一个背包都有五种巧克力板选择。

对于每个背包,从已排序的巧克力板中依次取出巧克力板,比较承重是否会超过背包的最大承重量,如果currentWeight + weights[j] <= maxWeight即当前背包尚有空余,那么这个巧克力板还能放入,否则跳过比较下一块巧克力板。

总结:

贪心能够通过每次选择当前最优的巧克力板,逐步构建出每个背包的最大装载量,从而达到全局最优解。排序后的贪心选择策略确保了在每个背包的最大承重范围内,尽可能多地装入巧克力板。