HDU 5410 CRB and His Birthday 混合背包(01背包和完全背包混合)

传送门HDU 5410



题目大意

你有M单位的钱,有N种东西,每种东西的花费为 Wi,每种东西买 x 个可以获得 Ai * x + Bi 的奖励,问最多可以获得的奖励是多少。


Sample Input
 
 
1 100 2 10 2 1 20 1 1
 
Sample Output
 
21



思路:

这个题是一看题一脸懵逼,然后一看题解觉得特别对,特别简单的题……感觉就是用到了抽象思维,不要去关注各种背包的原理和代码实现,而是去关注各种背包能做什么。我们发现无论买多少个同种物品都只加1个Bi,所以,可以把它看成买第1个的时候的奖励为 Ai + Bi,其他时候的奖励为 Ai。



具体实现

所以抽象到具体做法上就是对于每个物品先放入1个看看能导致的最大奖励值,然后再在放入1个的基础上放入多个,也就是先跑一遍01背包,再跑一遍完全背包。你可能会说,也可能在01背包的时候这种物品没放入,而在完全背包的时候放入这件物品了啊,这样就少加了个 Bi,其实这种情况是不可能的,只放一个的时候获得的奖励肯定比放入多个的时候更优,所以不放入第一个就放入第多个是不可能的。

#include<stdio.h>
#include<string.h>

int max(int a,int b)
{
	if(a>b) return a;
	else return b;
}

int main()
{
	int i,j,t,m,n,w[1010],a[1010],b[1010],dp[2010];
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&m,&n);
		for(i=1;i<=n;i++) scanf("%d%d%d",&w[i],&a[i],&b[i]);
		memset(dp,0,sizeof(dp));
		for(i=1;i<=n;i++)
		{
			for(j=m;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+a[i]+b[i]);
			for(j=w[i];j<=m;j++) dp[j]=max(dp[j],dp[j-w[i]]+a[i]);
		}
		printf("%d\n",dp[m]);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值