3269混合背包——codevs

没错  这就是基础题    我基础弱orz orz

今天才知道的这道题做法  orz orz

混合背包相比01和完全
就是多了个分类讨论

如果个数*体积超过空间
就作完全背包处理

否则二进制拆分作01处理 

只是注意二进制拆分后还要扫尾一次01


#include<cstdio>
#define loop(i,j,k) for(int i=j;i<=k;i++)
#define down_loop(i,j,k) for(int i=k;i>=j;i--)
#define max(a,b) a>b?a:b
#define MAXM (200000+10)
#define MAXN (200+10)
using namespace std;
int n,m;
int dp[MAXM];
int w[MAXN];
int v[MAXN];
int num[MAXN];
void readdata()
{
	scanf("%d%d",&n,&m);
	loop(i,1,n)
	{
	 scanf("%d%d%d",&v[i],&w[i],&num[i]);
	 num[i]=num[i]==-1?m/v[i]+5:num[i];
	 }	
}
void completebag(int i)
{
	loop(j,v[i],m)
	dp[j]=max(dp[j-v[i]]+w[i],dp[j]);
}
void zeroonebag(int vv,int ww)
{
	down_loop(j,vv,m)
	dp[j]=max(dp[j-vv]+ww,dp[j]);
}
void solve()
{
	loop(i,1,n)
	{		
		if(num[i]*v[i]>=m)
		completebag(i);		
		else
		{
		 	int k=1;
		 	int count=num[i];
		 	while(k<=count)
		 	{
		 		zeroonebag(k*v[i],k*w[i]);
		 		count-=k;
		 		k*=2;
		 	}
		 	if(count!=0)
		 	zeroonebag(count*v[i],count*w[i]);			
		}
	}
}
int main()
{	
	readdata();
	solve();
	printf("%d",dp[m]);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值