背包DP
- 两个特点:
- 一个物体有 大小 + 价值
- 有一个背包只能容纳某一个特定大小
-
要求:找最大价值
-
一般性转移方程——> 设背包大小为 ,有 个物品 , 物品价值为 物品大小为
-
设 表示任取 个物品在时间下取得的的最大值
-
初始化见下:
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
- 不装:
-
对 .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]);
}
}