1.0-1背包问题
每样东西只可以取一件
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
2.完全背包问题
每样物品可以取无数件
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<= v}
<pre class"example">
for i=1..N
for v=0..V
f[v]=max{f[v],f[v-c[i]]+w[i]};
3.多重背包问题
第i种物品最多有n[i]件可用
f[i][v]=max{f[i-1][v-k*c[i]]+ k*w[i]|0<=k<=n[i]}
4.混合三种背包问题
有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)
for i=1..N
if 第i件物品是01背包
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
else if 第i件物品是完全背包
for v=0..V
f[v]=max{f[v],f[v-c[i]]+w[i]};
再加上多重背包
如果再加上有的物品最多可以取有限次,那么原则上也可以给出O(VN)的解法:遇到多重背包类型的物品用单调队列解即可。但如果不考虑超过NOIP范围的算法的话,用P03中将每个这类物品分成O(log n[i])个01背包的物品的方法也已经很优了。