模板①:背包问题(0-1背包&完全背包&多重背包)

鉴于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 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值