背包问题

0/1 背包问题

给定 N 件物品,每件物品有 重量 w[i]价值 v[i],现有一个容量为 W 的背包,求能装入的最大总价值。

思路

  1. 定义状态

    • dp[i][j] 表示前 i 件物品,在容量 j 的背包下的最大价值。
  2. 状态转移方程

    • 不选第 i 件物品dp[i][j] = dp[i-1][j]
    • 选第 i 件物品(前提是能放得下)dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])
  3. 初始化

    • dp[0][j] = 0(背包容量为 j,但没有物品)
    • dp[i][0] = 0(有物品,但背包容量为 0
  4. 优化

    • 使用 滚动数组 降低空间复杂度,从 dp[i][j] 改为 dp[j],逆序遍历 j 以保证状态不被覆盖。
    • 0/1 背包问题的递归解法(C#)

      递归方法是一种 自顶向下(Top-Down) 的方式来解决 0/1 背包问题,适合理解 子问题拆解 的思想。但由于存在大量重复计算,需要使用 记忆化搜索(Memoization) 来优化效率。


      递归思路

      1. 定义递归函数

        • KnapsackRecursive(n, capacity) 表示前 n 个物品在总容量 capacity 下的最大价值。
      2. 状态转移方程

        • 如果不选当前物品KnapsackRecursive(n - 1, capacity)
        • 如果选当前物品(前提是容量足够)KnapsackRecursive(n−1,capacity−weights[n−1])+values[n−1]KnapsackRecursive(n - 1, capacity - weights[n-1]) + values[n-1]KnapsackRecursive(n1,capacityweights[n1])+values[n1]
        • 取两者的最大值dp[n,capacity]=max⁡(KnapsackRecursive(n−1,capacity),KnapsackRecursive(n−1,capacity−weights[n−1])+values[n−1])dp[n, capacity] = \max(KnapsackRecursive(n - 1, capacity), KnapsackRecursive(n - 1, capacity - weights[n-1]) + values[n-1])dp[n,capacity]=max(KnapsackRecursive(n1,capacity),KnapsackRecursive(n1,capacityweights[n1])+values[n1])
      3. 终止条件

        • n == 0capacity == 0 时,返回 0(没有物品或容量为 0)。
      4. 优化:记忆化搜索

        • 使用 memo[n, capacity] 记录已经计算过的结果,避免重复计算,提高效率。
    •  

    •  

posted @ 2025-02-20 13:58  MaxBruce  阅读(18)  评论(0)    收藏  举报