背包[ emmmm ]
—– 天泽龟
1、01 / 完全 / 多重 背包
1 | void zop(int c,int w){ //01 |
2、混合背包
分开处理,说着简单…
3、分组背包
先枚举容量,再枚举每组的物品
4、二维费用背包
碰到再说…
5、依赖背包
直接放题解… 题解
第一种方法 :对于每种 主件+附件 共五种情况(本题),枚举就行
第二种:背包九讲上关于依赖背包的方法。将每个主件和附件的集合看成一个物品组,可以先对主件及其附件集合进行一次 01 背包,得到费用一次为 $0…V - C_k$ 所有这些值时相应的最大价值 $F_k[0…V - C_k]$,那么这个主件及其附件集合相当于 $V - C_k + 1$个物品的物品组 ,其中费用为 $v$ 的物品价值为 $F_k[v - C_k] + W_k$ ,$v$ 的取值范围是 $C_k \leq v \leq V$ 。
然后再用分组背包的做法。
另一种:Solution [NOIP提高组2006]金明的预算方案
6、树形背包…
待补…
7、背包问题的变化
1)打印方案
我们设 $g[i][j]$表示当 $ f[i][j]$状态时的转移来源, $g[i][j]=0$即从 $ f[i-1][j]$ 转来的,$ g[i][j]=1$即从$ f[i-1][j-v[i]]$ 转移的.
1 | fd(i,n,0) // 这里应和求背包时的顺序相反 |
2)求方案数
例题 1 :小A点菜
只需要把转移方程改成 $ f[j]=\sum_{i=0}^n (f[j−v[i]]+w[i])$ 具体到就是 :
$f[i]=max(f[i],f[i-c]+w) \rightarrow f[i]=f[i]+f[i-c]$ , $f[0]=1$
例题 2 :自然数累加问题
给定一个数 s ,在 1~to~n 中,求可累加任意数等于 s 的方案数。
给定一个正整数n,求将其分解成若干个素数之和的方案总数。
每个素数可以选若干次,如果可以。完全背包计数,正着计数
1 | for(int i=c;i<=n;i++)//f[0]=1; |
例题4:P1077 摆花
看着像多重背包计数?其实不是,对于每一种花,只能选择一个数量,比如选择了三个,不能拆成 2 + 1,否则会重复计数。其实更像分组背包,只能选择其中一个固定的值。
1 | f[0]=1ll; |
3)特定顺序的背包
例题:烹调方案
每件物品的价值和时间有关系。先排序后,套 01 背包。