🍪🧁🍧

背包问题

01背包问题

首先要写出状态转移方程

i的编号从1开始
只装前i个物品,背包容量为c时背包能装的最大价值

dp[i,c] = Math.max( dp[i-1, c] , dp[i-1, c-wgt[i] ] + val[i])

判定边界条件

装的物品为0 ,即 i0 时dp为0
背包容量为0,即 c
0 时dp为0

  • 递归
/* 0-1 背包:记忆化搜索 */
function knapsackDFSMem(wgt, val, mem, i, c) {
    // 若已选完所有物品或背包无剩余容量,则返回价值 0
    if (i === 0 || c === 0) {
        return 0;
    }
    // 若已有记录,则直接返回
    if (mem[i][c] !== -1) {
        return mem[i][c];
    }
    // 若超过背包容量,则只能选择不放入背包
    if (wgt[i - 1] > c) {
        return knapsackDFSMem(wgt, val, mem, i - 1, c);
    }
    // 计算不放入和放入物品 i 的最大价值
    const no = knapsackDFSMem(wgt, val, mem, i - 1, c);
    const yes =
        knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];
    // 记录并返回两种方案中价值更大的那一个
    mem[i][c] = Math.max(no, yes);
    return mem[i][c];
}
  • 动态规划
/* 0-1 背包:动态规划 */
function knapsackDP(wgt, val, cap) {
    const n = wgt.length;
    // 初始化 dp 表
    const dp = Array(n + 1)
        .fill(0)
        .map(() => Array(cap + 1).fill(0));
    // 状态转移
    for (let i = 1; i <= n; i++) {
        for (let c = 1; c <= cap; c++) {
            if (wgt[i - 1] > c) {
                // 若超过背包容量,则不选物品 i
                dp[i][c] = dp[i - 1][c];
            } else {
                // 不选和选物品 i 这两种方案的较大值
                dp[i][c] = Math.max(
                    dp[i - 1][c],
                    dp[i - 1][c - wgt[i - 1]] + val[i - 1]
                );
            }
        }
    }
    return dp[n][cap];
}
posted @ 2025-07-17 20:49  不想吃fun  阅读(6)  评论(0)    收藏  举报