|
|
|
@ -3,7 +3,8 @@
|
|
|
|
|
### 一、题目描述
|
|
|
|
|
有 $N$ 组物品和一个容量是 $V$ 的背包。
|
|
|
|
|
|
|
|
|
|
每组物品有若干个,同一组内的物品最多只能选一个。
|
|
|
|
|
每组物品有若干个,**同一组内的物品最多只能选一个**。
|
|
|
|
|
|
|
|
|
|
每件物品的体积是 $v_{ij}$,价值是 $w_{ij}$,其中 $i$ 是组号,$j$ 是组内编号。
|
|
|
|
|
|
|
|
|
|
求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
|
|
|
|
@ -57,25 +58,19 @@ $0<v_{ij},w_{ij}≤100$
|
|
|
|
|
#### 状态表示
|
|
|
|
|
$f[i][j]$ 从前 $i$ 组物品中选择且总体积不大于 $j$ 的最大价值
|
|
|
|
|
|
|
|
|
|
#### 状态计算
|
|
|
|
|
针对第 $i$ 组物品,将整个状态划分成 $s[i]+1$ 类:
|
|
|
|
|
* 第$i$组物品一个都不要:$f[i][j] = f[i-1][j]$
|
|
|
|
|
* 选第 $i$ 组物品的第一个物品:$f[i][j] = f[i-1][j-v[1]]+w[1]$
|
|
|
|
|
* 选第 $i$ 组物品的第二个物品:$f[i][j] = f[i-1][j-v[2]]+w[2]$
|
|
|
|
|
* 选第 $i$ 组物品的第 $k$ 个物品:$f[i][j] = f[i-1][j-v[k]]+w[k]$
|
|
|
|
|
|
|
|
|
|
#### 状态转移
|
|
|
|
|
$$\large f[i][j]=max(f[i][j], f[i-1][j-v[k]]+w[k])), k=0, 1, 2,...,s[i]$$
|
|
|
|
|
针对第 $i$ 组物品,将整个状态划分成 $s[i]+1$ 类:
|
|
|
|
|
* ① 第$i$组物品一个都不要:$f[i][j] = f[i-1][j]$
|
|
|
|
|
* ② 选第 $i$ 组物品的第一个物品:$f[i][j] = f[i-1][j-v_1]+w_1$
|
|
|
|
|
* ③ 选第 $i$ 组物品的第二个物品:$f[i][j] = f[i-1][j-v_2]+w_2$
|
|
|
|
|
* ④ 选第 $i$ 组物品的第 $k$ 个物品:$f[i][j] = f[i-1][j-v_k]+w_k$
|
|
|
|
|
* ...
|
|
|
|
|
|
|
|
|
|
#### 状态初始化
|
|
|
|
|
$f[0][0\sim m] = 0$ 表示在选择 `0` 件物品时对于任何体积来讲,其最大价值均为 `0`
|
|
|
|
|
$$\large f[i][j]=max(f[i][j], f[i-1][j-v_k]+w_k)) \ k \in [0, 1, 2,...,s_i]$$
|
|
|
|
|
|
|
|
|
|
同理,分组背包问题也是可以从二维优化到一维的。其实只需要谨记两点:
|
|
|
|
|
- **当前状态需要用上层状态转移时,从大到小枚举体积**
|
|
|
|
|
- **当前状态需要用本层状态转移时,从小到大枚举体积**
|
|
|
|
|
#### 初始化
|
|
|
|
|
$f[0][0\sim m] = 0$ 表示在选择 `0` 组物品时对于任何体积来讲,其最大价值均为 `0`
|
|
|
|
|
|
|
|
|
|
<font color='red' size=4><b>总结: 每个组中可以一个也不选,选也只能选择1个
|
|
|
|
|
</b></font>
|
|
|
|
|
|
|
|
|
|
### 三、二维数组版本
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|