m为最大负担的费用
w[i]为第i个物品的花费
v[i]为第i个物品的价值
01背包
for i:=1 to n do
for j:=m downto w[i] do
f[j]:=max(f[j],f[j-w[i]]+v[i]);
初始化
- 恰好装满
for i:=1 to n do
f[i]:=-maxlongint;
f[0]:=0;
- 不用装满
for i:=1 to n do
f[i]:=0;
f[0]:=0;
- 当要输出最小值时应赋值为maxlongint,但会超longint,应赋值为max(v[i])+1
完全背包
一维
for i:=1 to n do
for j:=w[i] to m do
f[j]:=max(f[j],f[j-w[i]]+v[i]);
二维
for i:=1 to n do
for j:=1 to m do
if j-a[i]>=0
then f[i,j]:=max(f[i-1,j],f[i,j-a[i]]+b[i])
else f[i,j]:=f[i-1,j]; //注意注意没有这句就是错的!!!
多重背包
- 转化为01背包
ci:=0;
for i:=1 to n do
begin
readln(a,b,c); //a:该物品的花费,b:该物品的价值,c:该物品的数量
for j:=1 to c do
begin
inc(ci);
w[ci]:=a; v[ci]:=b;
end;
end;
- 二进制思想优化
我们想对于有x个价值为y的物品,将x分解为 20+21+...+2k+(x−2k+1) 这样物品1..x个的方案都可以通过 logk 个物品做01背包来实现 - 单调队列优化