java解法

有一个容量上限为 maxPower 的背包,以及 count 个物品,每个物品的“能力值”存储在数组 powerOutputs 中。
每个物品只能被选择一次,目标是找到一个组合,使得总能力值尽可能接近(但不超过)maxPower,并输出最大总和。
解决方案

这是一个典型的 0-1 背包问题:
使用动态规划解决,定义 dp[j] 表示在容量为 j 时能够达到的最大能力值。
遍历每个物品,对于每个物品的能力值 powerOutputs[i],更新 dp 数组:
如果选择当前物品,更新 dp[j] = max(dp[j], dp[j - powerOutputs[i]] + powerOutputs[i])。
如果不选择当前物品,保持 dp[j] 不变。
使用倒序更新 dp 数组以确保每个物品只被使用一次。
算法流程

初始化一个大小为 maxPower + 1 的数组 dp,所有元素初始化为 0。
遍历每个物品的能力值 powerOutputs[i]:
从后向前遍历容量 j,范围是 [maxPower, powerOutputs[i]]。
更新 dp[j] 的值。
遍历所有物品后,dp[maxPower] 即为能够达到的最大总能力值

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        // 读取物品数量
        int count = input.nextInt();

        // 读取每个物品的能力值
        int[] powerOutputs = new int[count];
        for (int i = 0; i < count; i++) {
            powerOutputs[i] = input.nextInt();
        }

        // 读取背包的最大容量
        int maxPower = input.nextInt();

        // 调用动态规划方法计算最优能力值
        System.out.println(findOptimalPower(count, powerOutputs, maxPower));
    }

    /**
     * 使用动态规划求解背包问题,寻找最大能力值总和
     *
     * @param count 物品数量
     * @param powerOutputs 每个物品的能力值
     * @param maxPower 背包的最大容量
     * @return 能够达到的最大能力值总和
     */
    public static int findOptimalPower(int count, int[] powerOutputs, int maxPower) {
        // 动态规划数组,表示容量为 j 时的最大能力值
        int[] dp = new int[maxPower + 1];

        // 遍历每个物品
        for (int i = 0; i < count; i++) {
            // 从后向前更新 dp 数组,确保每个物品只使用一次
            for (int j = maxPower; j >= powerOutputs[i]; j--) {
                // 更新 dp[j],选择或不选择当前物品
                dp[j] = Math.max(dp[j], dp[j - powerOutputs[i]] + powerOutputs[i]);
            }
        }

        // 返回能够达到的最大能力值
        return dp[maxPower];
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

给定一个数组 powers 表示若干个物品的能力值,以及一个整数 maxPower 表示背包的容量上限。
目标是从 powers 中选择若干物品,使得其能力值总和尽可能接近(但不超过)maxPower,并输出最大总和。
解决方案

使用递归 + 记忆化(动态规划)解决问题。
定义递归函数 findMax(index, remainingPower):
index 表示当前正在考虑的物品索引。
remainingPower 表示背包剩余的容量。
返回在当前状态下能够达到的最大能力值总和。
记忆化数组 memo 用于存储中间结果,避免重复计算:
memo[index][remainingPower] 表示从物品 index 开始、背包剩余容量为 remainingPower 时能够达到的最大能力值。
递归逻辑

终止条件:
如果当前物品索引 index 已超出数组范围,返回 0(表示没有更多物品可选)。
状态转移:
不选择当前物品:结果为 findMax(index + 1, remainingPower)。
选择当前物品(如果其能力值不超过剩余容量):结果为 powers[index] + findMax(index + 1, remainingPower - powers[index])。
最终结果为上述两种选择的最大值。

const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

const lines = [];

// 读取输入数据
rl.on("line", (line) => {
    lines.push(line);

    // 当读取到 3 行数据时,开始处理
    if (lines.length === 3) {
        const n = parseInt(lines[0]); // 物品数量
        const powers = lines[1].split(" ").map(Number); // 物品能力值数组
        const maxPower = parseInt(lines[2]); // 背包容量

        // 调用主函数,计算结果
        console.log(getOptimalPower(n, powers, maxPower));

        // 重置输入缓冲区
        lines.length = 0;
    }
});

/**
 * 主函数:计算背包问题的最优解
 * @param {number} n 物品数量
 * @param {number[]} powers 物品能力值数组
 * @param {number} maxPower 背包的最大容量
 * @returns {number} 能够达到的最大能力值
 */
function getOptimalPower(n, powers, maxPower) {
    // 初始化记忆化数组,默认值为 -1,表示尚未计算
    const memo = Array(n)
        .fill(null)
        .map(() => Array(maxPower + 1).fill(-1));

    // 调用递归函数,返回最终结果
    return findMax(0, maxPower, powers, memo);
}

/**
 * 递归函数:计算从当前物品开始、剩余容量为 remainingPower 时的最大能力值
 * @param {number} index 当前物品索引
 * @param {number} remainingPower 背包剩余容量
 * @param {number[]} powers 物品能力值数组
 * @param {number[][]} memo 记忆化数组
 * @returns {number} 当前状态下能够达到的最大能力值
 */
function findMax(index, remainingPower, powers, memo) {
    // 递归终止条件:如果已经处理完所有物品,返回 0
    if (index === powers.length) return 0;

    // 如果当前状态已经计算过,直接返回缓存值
    if (memo[index][remainingPower] !== -1) return memo[index][remainingPower];

    // 不选择当前物品
    let withoutCurrent = findMax(index + 1, remainingPower, powers, memo);

    // 选择当前物品(如果能力值不超过剩余容量)
    let withCurrent = 0;
    if (powers[index] <= remainingPower) {
        withCurrent =
            powers[index] +
            findMax(index + 1, remainingPower - powers[index], powers, memo);
    }

    // 记录当前状态的最优解,并返回
    memo[index][remainingPower] = Math.max(withoutCurrent, withCurrent);
    return memo[index][remainingPower];
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/145064467"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!