什么是0/1背包?
传送门:个人认为这个视频讲的不错
初始化
下面是本蒟蒻的一些个人理解,请见谅
众所周知,01背包有两种初始化形式:
- 初始化为0, f [ j ] f[j] f[j]表示不要求装满时背包容积为 j j j的最大价值;
- f [ 0 ] f[0] f[0]初始化为0, f [ 1 − n ] f[1-n] f[1−n]初始化为 − ∞ - \infty −∞, f [ j ] f[j] f[j]表示恰好装满时背包容积为 j j j的最大价值。
这是为什么呢?
原理很简单,此处,方法2中的 − ∞ - \infty −∞可以理解为没有满足条件(即恰好装满)的最优解。
由于01背包状态转移公式:
/*
n 物品数
m 背包容积
v[i] 第i个物品的体积
w[i] 第i个物品的价值
f 状态
*/
for (int i=1;i<=n;i++)
for(int j=m;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);//状态转移方程
若一定要求装满:
- 则必有
j=v[i]
- 所以
f[j-v[i]]+w[i]=f[0]+w[i]=w[i]
- 若无法刚好装满,则
j!=v[i]
,即f[j-v[i]]+w[i]=-inf
- 所以此时需要再遍历一遍找最终答案ans:
for (int j=0;j<=m;j++) ans=max(ans,f[j]);//因为不一定装满m
反之,同理,不要求装满即可赋初值为0,
直接输出答案为f[m]
。