背包问题 动态规划

背包DP

  • 两个特点:
  1. 一个物体有 大小 + 价值
  2. 有一个背包只能容纳某一个特定大小
  • 要求:找最大价值

  • 一般性转移方程——> 设背包大小为 ,有 个物品 , 物品价值为 物品大小为

  • 表示任取 个物品在时间下取得的的最大值

  • 初始化见下

vector<vector<int>> dp(Y,vector<int>(N+1,0)); 
//对[0]行的初始
for (size_t i = size[0]; i <= N; i++) {
    dp[0][i] = val[0];
}
//对[0]列的初始
//在背包初始大小为0的情况,只有 size = 0 的物品可以被装下
for(size_t j = 0; j <= Y ; j++){
    dp[i][0] = 0;
}
  • 现在我们来推递推方程:

  • 对于一个 而言表示的是在 背包大小下取得 前 的最大值

  • 有两种情况

    1. = 即当前容量装不下 这个物品,只能与前一个的价值相同 = 即增加的
    2. : .1
    3. 不装:
  • .1 的解释: 选择装下大小为 价值为 的物品,那对 到的 而言:

    • 表示选取的范围 那显然
    • 表示背包容量大小 : 既然我们选取了这个物品 , 那我们就看对于没有该物品时候的背包大小所表示的价值 + 这个物品 的价值即:
    • 本质是最大价值,则我们需要加上所选物品的价值 即:
  • 在选择 的两种情况下选择较大的一方表示最大价值

  • 即完整递推表达式为:

代码表示见下

for (size_t i = 1; i < m; i++) {
    for (size_t j = 1; j <= t; j++) {
        if (j < size[i])
            dp[i][j] = dp[i - 1][j];
        else
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - size[i]] + val[i]);
    }
}