多重背包
也就是说限定物品选择的个数。
vi ci ki //对于第i个物品,体积为vi,价值ci,只能选择ki次。
① 将 ki 分为 ki 个物品,然后用01背包解决。
代码:
for (int i=1;i<=n;i++)
{
scanf("%d%d%d",&v,&c,&k);
for (int j=1;j<=k;j++)
s[++cnt].v=v,s[cnt].c=c;
}
② 采用类似lca的方法,将k个物品分为 1,2,4,8,16,..... 2^n.
这样对于每一个1-ki之间自然数i都可以被组合出来。然后再采用01背包。
二进制拆分一定要覆盖当前的点。
代码:
while
(n--)
//接下来输入n中这个物品
{
scanf("%d%d%d", &vi, &ci, &ki);
//输入每种物品的数目和价值
for (int k=1; k<=ki;
k<<=1)
//<<左移相当于乘二
{
value[cnt]=k*vi;//体积 每个二进制分法的物品体积和价值都要×k
size[cnt++]=k*ci;//价值
ki-=k;
}
if (ki>0) //如果最后ki分割有剩余,那么就把剩余的当做一种情况
{
value[cnt]=ki*vi;
size[cnt++]=ki*ci;
}