鉴于NOIP临近,打算来写写模板。。。
//0-1背包
//外层循环枚举放的东西,内层循环枚举背包的最大容量到当前物品的容量
void zeroone_pack(int *f,int c,int w)
{
for(int i=v;i>=c;i--)//v为背包的最大容量
f[i]=max(f[i-c]+w,f[i]);//比较当前这个位置放这个物品还是不放这个物品更优
}
//完全背包
//外层循环枚举放的东西,内层循环枚举当前物品的重量到背包的最大重量
void complete_pack(int *f,int c,int w)
{
for(int i=c;i<=v;i++)
f[i]=max(f[i-c]+w,f[i]);
}
//计算当前有多少种方案可以完全装完这个背包
f[0]=1;
void complete_pack(int *f,int c)
{
for(int i=c;i<=v;i++)
f[i]+=f[i-c];
}
//多重背包
//如果背包的个数乘以背包的容积大于背包的最大容量转化为完全背包
//其余的转化为二的次方数的加法,如果剩余的情况小于下一个用2的次方数表示的数,最后一种情况就是剩余的数
//这个保证可以将所有的情况取到,eg.13=1+2+4+6,5=1+2+2;
void multiple_pack(int m,int c,int w)
{
if(c*m>v)
{
complete_pack(f,c,w);
return ;
}
int k=1;
while(k<m)
{
zeroone_pack(f,c*k,w*k);
m-=k;
k*=2;
}
zeroone_pack(f,c*m,w*m);
return ;
}