HDU2161

原文链接: HDU2161

上一篇: HDU1003 Max Sum

下一篇: 01背包方案数

多重背包,转化为01背包

#include <iostream>
#include <cstdio>

using namespace std;
#define MAX 111111
int dp[MAX];
int price[MAX],hight[MAX],cnt[MAX];		//价格,重量,数目 
int c[MAX],w[MAX];		//新物品的价值,重量 
int main(int argc, char *argv[])
{
	int T;
	scanf("%d",&T);
	while(T--){
		int money,m;
		scanf("%d%d",&money,&m);
		int num=1;		//新物品由数组下标为1 处开始放置 
		for(int i=1;i<=m;i++){
			scanf("%d",price+i);
			scanf("%d",hight+i);
			scanf("%d",cnt+i);
			
			//转化物品
			for(int j=1;j<=cnt[i];j<<=1){
				c[num] = j*price[i];
				w[num++] = j*hight[i];
				cnt[i]-=j; 
			} 
			if(cnt[i]>0){
				c[num]=cnt[i]*price[i];
				w[num++] = cnt[i]*hight[i];
			}
		}	
		
		//01背包
		memset(dp,0,sizeof(dp));
		//注意此时num是比背包中的数目大一的 
		for(int i=1;i<num;i++){
			for(int j=money;j>=c[i];j--){
				dp[j]=max(dp[j],dp[j-c[i]]+w[i]);
			} 
		}	
		
	 	printf("%d\n",dp[money]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值