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

来源:互联网 发布:软件行业职位分类 编辑:程序博客网 时间:2024/05/16 19:04

传送门:HDU 5410


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


Sample Input
1100 210 2 120 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;}

阅读全文
1 0
原创粉丝点击