1.简单01背包
##一维数组优化
for i=1...N
for v=V...cost
f[v]=max{f[v],f[v-cost]+weight};
##常数优化
for(int i=1;i<=n;i++)
{
sumw+=w[i];
bound=max(m-sumw,w[i]);
for(int c=m;c>=bound;c--)
{
if(c>=w[i])
f[c]=max(f[c],f[c-w[i]]+v[i]);
}
}
2.简单完全背包
for i=1...N
for v=0...V
f[v]=max{f[v],f[v-cost]+weight};
如果只用滚动数组优化完全背包和01背包的话,只需要改变v的递推顺序就可完成。
而01背包需要保证v的逆序的原因的是01背包需要保证每个物品只选一次。
3.多重背包
procedure MultiplePack(cost,weight,amount)
if cost*amount>=V
CompletePack(cost,weight)
return
integer k=1
while k<amount
ZeroOnePack(k*cost,k*weight)
amount=amount-k
k=k*2
ZeroOnePack(amount*cost,amount*weight)
4.混合背包
p01,p02,p03混合问题,考虑好上述三个问题就行。
5.分组背包
for 所有的组k
for v=V..0
for 所有的i属于组k
f[v]=max{f[v],f[v-c[i]]+w[i]}
6.有依赖的背包
我们可以对主件i的“附件集合”先进行一次01背包,得到费用依次为0…V-c[i]所有这些值时相应的最大价值f’[0…V-c[i]]。那么这个主件及它的附件集合相当于V-c[i]+1个物品的物品组,其中费用为c[i]+k的物品的价值为f’[k]+w[i]。也就是说原来指数级的策略中有很多策略都是冗余的,通过一次01背包后,将主件i转化为V-c[i]+1个物品的物品组,就可以直接应用P06的算法解决问题了。
典型例题:https://www.luogu.org/problemnew/show/P1064