菜得只能背模板…QAQ
N为物品数,V为背包体积
v[i],w[i],s[i]分别表示第i件物品的体积、价值、数量
01背包(求最大价值)
每种物品只有一件
模板题:AcWing 01背包问题
f[j]表示体积最大为j的最大价值
答案为f[V]
for(int i=1;i<=N;i++)
{
for(int j=V;j>=v[i];j--)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
完全背包(求最大价值)
每种物品有无限多件
模板题:AcWing 完全背包问题
答案为f[V]
for(int i=1;i<=N;i++)
{
for(int j=v[i];j<=V;j++)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
多重背包(求最大价值)
每种物品有若干件
模板题:AcWing 多重背包问题
答案为f[V]
for(int i=1;i<=N;i++)
{
for(int j=V;j>=v[i];j--)
{
for(int k=0;k<=s[i]&&k*v[i]<=j;k++)
{
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
}
}
}
01背包(求方案数)
给了物品体积和价值,求最优选法(最大价值)的方案数
模板题:AcWing 背包问题求方案数
f[j]表示最大体积为j的最大价值
cnt[j]表示最大体积为j的最大价值的方案数
答案为cnt[V]
for(int i=0;i<=V;i++)
cnt[i]=1;
for(int i=1;i<=N;i++)
{
for(int j=V;j>=v[i];j--)
{
if(f[j]<f[j-v[i]]+w[i])
{
f[j]=f[j-v[i]]+w[i];
cnt[j]=cnt[j-v[i]];
}
else if(f[j]==f[j-v[i]]+w[i])
{
cnt[j]=cnt[j]+cnt[j-v[i]];
}
}
}
其他变形题
1.给出物品的体积,(每种物品只有一件)求把背包装满最多有几种方案
f[j]表示最大体积为j时的最大方案数
答案为f[V]
f[0]=1;
for(int i=1;i<=N;i++)
{
for(int j=V;j>=v[i];j--)
{
f[j]=f[j]+f[j-v[i]];
}
}
2.给出物品的体积,(每种物品无限多件)求把背包装满最多有几种方案
答案为f[V]
f[0]=1;
for(int i=1;i<=N;i++)
{
for(int j=v[i];j<=V;j++)
{
f[j]=f[j]+f[j-v[i]];
}
}
3.给出物品的体积,(每种物品只有一个)求背包最多能装多大体积
本质还是求最大价值,其实就是体积和价值等价了
例题:计蒜客 干草出售
答案为f[V]
for(int i=1;i<=N;i++)
{
for(int j=V;j>=v[i];j--)
{
f[j]=max(f[j],f[j-v[i]]+v[i]);
}
}