|
|
|
@ -178,22 +178,27 @@ int main() {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 七、疑问解答
|
|
|
|
|
#### $Q1$:为什么可以引入单调队列对多重背包进行优化?
|
|
|
|
|
$A$:因为朴素版本三层循环,太慢了,要想办法优化?怎么优化的呢?因为发现每个新值要想更新$f[i][j]$值,第$i$件物品,最多有$s_i$件,我们可以选择$0 \sim s_i$个,同时,由于$i$物品的体积是$v_i$,也就是我们在拿物品$i$时,有一个关系
|
|
|
|
|
|
|
|
|
|
<div class="center">
|
|
|
|
|
#### $Q_1$:原理解析
|
|
|
|
|
多重背包:物品个数是复数个,但又不是无限个。
|
|
|
|
|
- 当作$01$背包来理解,$s$个物品当成$s$次$01$背包操作。然后优化的话通过 **二进制** 来优化。
|
|
|
|
|
- 当作完全背包来理解,就是有数量限制的完全背包,而这个数量限制就可以理解成 **滑动窗口的长度**,然后优化通过 **单调队列** 来优化。
|
|
|
|
|
|
|
|
|
|
| | 拿$0$个 | 拿$1$个 | 拿$2$个 | ... | 拿$s$个 |
|
|
|
|
|
| ---- | ----------- | --------------- | ------------------- | --- | ------------------- |
|
|
|
|
|
| 体积 | $k$ | $k-v$ | $k-2*v$ | ... | $k-s*v$ |
|
|
|
|
|
| 价值 | $f[i-1][k]$ | $f[i-1][k-v]+w$ | $f[i-1][k-2*v]+2*w$ | ... | $f[i-1][k-s*v]+s*w$ |
|
|
|
|
|
</div>
|
|
|
|
|
队列的单调性就是基于
|
|
|
|
|
$$f[i][j] = max(f[i - 1][j], f[i - 1][j - v] + w,.....,f[i - 1][j - k * v] + k * w$$
|
|
|
|
|
|
|
|
|
|
要将前$i - 1$个物品的方案基础上不停尝试放入第$i$个物品,遍历取最大值。
|
|
|
|
|
$f[i - 1][j - k*v] + k *w$表示,总空间是$j$,有且仅有$k$个物品$i$,其余空间通过前$i - 1$个物品填充的最大价值。
|
|
|
|
|
|
|
|
|
|
多重背包因为有数量限制,向前遍历的个数$k$是受到数量$s$限制的。
|
|
|
|
|
|
|
|
|
|
所以要将$max$中的每个元素$f[i - 1][j], f[i - 1][j - v] + w,.....,f[i - 1][j - k * v] + k * w$,通过维护单调队列,来获得当前窗口宽度$s$范围内的最大值。
|
|
|
|
|
|
|
|
|
|
并且在$j = j + v$后,队列中所有元素对应状态与当前背包空间差增加了$v$,可以多放一个物品$i$,每个元素对应的价值增加$w$,全部都加一个$w$,所以单调性不发生任何变化。
|
|
|
|
|
|
|
|
|
|
**总结**:
|
|
|
|
|
* 往前最多看$s$个
|
|
|
|
|
* $f[i][j]$ <font color='red' size=4><b> 跳跃性依赖 </b></font>于$f[i-1][j - x * v]$,想要求什么呢?求离我距离最多$s$个数的最大值。这数不用每次现去查找,可用单调队列动态维护来优化查询。
|
|
|
|
|
两种优化可以理解成两种思路的进化路线。
|
|
|
|
|
|
|
|
|
|
#### $Q2$:单调队列中装的是什么?
|
|
|
|
|
#### $Q_2$:单调队列中装的是什么?
|
|
|
|
|
$A$:是体积,是$f[i][j]$可以从哪些 **体积** 转移而来。比如当前$i$物品的体积是$v_i=2$,个数是$3$,那么$f[i][j]$可以从
|
|
|
|
|
$$
|
|
|
|
|
\large \left\{\begin{array}{l}
|
|
|
|
@ -205,7 +210,7 @@ $$
|
|
|
|
|
$$
|
|
|
|
|
转移而来,当然,还需要判断一下是不是你的背包能装下那么多,一旦装不下了就别硬装了。
|
|
|
|
|
|
|
|
|
|
#### $Q3$:只记录体积怎么计算最大价值?
|
|
|
|
|
#### $Q_3$:只记录体积怎么计算最大价值?
|
|
|
|
|
$A$:只记录了所关联的体积,最大价值是现用现算的,办法是
|
|
|
|
|
$$\large f[i][k] = f[i - 1][q[hh]] + (k - q[hh]) / v * w$$
|
|
|
|
|
|
|
|
|
|