|
|
|
@ -110,29 +110,24 @@ int main() {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 三、完全背包—经典优化
|
|
|
|
|
使用瞪眼大法,观察 $f(i,j)$ 的 **状态转移方程** 进行变形
|
|
|
|
|
尝试找出$f(i,j)$与它的前序$f(i,j-v_i)$之间的关联关系,看看能不能实现$f(i,j-v_i)->f(i,j)$的迁移:
|
|
|
|
|
对 $f(i,j)$ 的 **状态转移方程** 进行变形
|
|
|
|
|
尝试找出$f(i,j)$与它的前序$f(i,j-v_i)$之间的关联关系,看看能否实现$f(i,j-v_i) \rightarrow f(i,j)$的迁移:
|
|
|
|
|
|
|
|
|
|
$$\large f(i,j)=f(i-1,j)+f(i-1,j-v_i)+...+f(i-1,j-s\cdot v_i)①$$
|
|
|
|
|
|
|
|
|
|
$$\large f(i,j-v_i)= f(i-1,j-v_i)+...+f(i-1,j-s\cdot v_i)②$$
|
|
|
|
|
|
|
|
|
|
<font color='red' size=4><b>注:把体积$j-v_i$代入①式,就可以得到 ②式</b></font>
|
|
|
|
|
> <font color='red' size=4><b>注:把体积$j-v_i$代入①式,就可以得到 ②式</b></font>
|
|
|
|
|
|
|
|
|
|
<font color='blue' size=4><b>$Q:$①和②中的$s$是一个值吗?</b></font>
|
|
|
|
|
**答**:是一个值的。从事情本质出发,思考一下$s\cdot v_i$的含义:在$j$这么大的空间限制下,最多可以装多少个$i$物品,当然是同一个个数值$s$了。
|
|
|
|
|
**答**:是一个值。从事情本质出发,$s\cdot v_i$含义:在$j$这么大的空间限制下,最多可以装多少个$i$物品,当然是同一个个数值$s$了。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
由上述两个等式可以获得如下递推式:
|
|
|
|
|
$$\LARGE f(i,j)=f(i−1,j)+f(i,j−v_i)$$
|
|
|
|
|
$$\large f(i,j)=f(i−1,j)+f(i,j−v_i)$$
|
|
|
|
|
|
|
|
|
|
把这个等式作为 **状态转移方程** ,就可以把时间复杂度优化到 $O(n \times m)$
|
|
|
|
|
同时,观察到该 **转移方程** 对于第 $i$ 阶段的状态,只会使用第 $i-1$ 层和第 $i$ 层的状态
|
|
|
|
|
新的 **状态转移方程** ,时间复杂度 $O(n \times m)$
|
|
|
|
|
|
|
|
|
|
因此我们也可以采用 **$01$背包** 的 空间优化方案
|
|
|
|
|
|
|
|
|
|
时间复杂度:$O(n×m)$
|
|
|
|
|
空间复杂度:$O(m)$
|
|
|
|
|
|
|
|
|
|
#### 二维优化版本
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
@ -158,6 +153,15 @@ int main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
观察到该 **转移方程** 对于第 $i$ 阶段的状态,只会使用第 $i-1$ 层和第 $i$ 层的状态
|
|
|
|
|
|
|
|
|
|
因此我们也可以采用 **$01$背包** 的 空间优化方案
|
|
|
|
|
|
|
|
|
|
时间复杂度:$O(n×m)$
|
|
|
|
|
|
|
|
|
|
空间复杂度:$O(m)$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 一维优化解法
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|