hdu 5410 CRB and His Birthday(混合背包)

Problem Description

Today is CRB‘s birthday. His mom decided to buy many presents for her lovely son. She went to the nearest shop with M Won(currency unit). At the shop, there are N kinds of presents. It costs Wi Won to buy one present of i-th kind. (So it costs k × Wi Won to buy k of them.) But as the counter of the shop is her friend, the counter will give Ai × x + Bi candies if she buys x(x>0) presents of i-th kind. She wants to receive maximum candies. Your task is to help her. 1 ≤ T ≤ 20 1 ≤ M ≤ 2000 1 ≤ N ≤ 1000 0 ≤ Ai, Bi ≤ 2000 1 ≤ Wi ≤ 2000

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case: The first line contains two integers M and N. Then N lines follow, i-th line contains three space separated integers Wi, Ai and Bi.

Output

For each test case, output the maximum candies she can gain.

Sample Input

1
100 2
10 2 1
20 1 1

Sample Output

21

Hint

CRB‘s mom buys 10 presents of first kind, and receives 2 × 10 + 1 = 21 candies.

Author

KUT(DPRK)

Source

2015 Multi-University Training Contest 10

题意:你有M块钱,现在有N件商品

第i件商品要Wi块,如果你购买x个这样的商品,你将得到Ai*x+Bi个糖果

问能得到的最多的糖果数

 

思路:非常好的一道01背包和完全背包结合的题目

首先,对于第i件商品,如果只买1个,得到的价值是Ai+Bi

如果在买1个的基础上再买,得到的价值就是Ai

也就是说,除了第一次是Ai+Bi,以后购买都是Ai

那么,我们能否将i商品拆分成两种商品,其中两种商品的代价都是Wi,

第一种的价值是Ai+Bi,但是只允许买一次

第二种的价值是Ai,可以无限次购买

 

接下来我们来讨论这样拆的正确性

理论上来讲,买第二种之前,必须要买第一种

但是对于这道题,由于Ai+Bi>=Ai是必然的,因为Bi肯定是非负

所以对于代价相同,价值大的肯定会被先考虑

换句话来说,如果已经开始考虑第二种商品了,那么第一种商品就肯定已经被添加到背包里了~

 

所以,这题我们把n件商品拆分成2*n件商品,对于第一种商品做01背包,对于第二种商品做完全背包,这样就把题目转换成了非常熟悉的题目,也就能顺利AC了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define N 1006
 6 int v,n;
 7 int w[N<<1],a[N<<1],b[N<<1];
 8 int dp[N<<1];
 9 int main()
10 {
11     int t;
12     scanf("%d",&t);
13     while(t--)
14     {
15         scanf("%d%d",&v,&n);
16         for(int i=1;i<=n;i++)
17         {
18             int x,y,z;
19             scanf("%d%d%d",&x,&y,&z);
20             w[i]=x,a[i]=y+z;
21             w[i+n]=x,a[i+n]=y;
22         }
23         memset(dp,0,sizeof(dp));
24
25         for(int i=1;i<=n;i++)
26         {
27             for(int j=v;j>=w[i];j--)
28             {
29                 dp[j]=max(dp[j],dp[j-w[i]]+a[i]);
30             }
31         }
32
33         for(int i=n+1;i<=2*n;i++)
34         {
35             for(int j=w[i];j<=v;j++)
36             {
37                 dp[j]=max(dp[j],dp[j-w[i]]+a[i]);
38             }
39         }
40
41         printf("%d\n",dp[v]);
42
43     }
44     return 0;
45 }

时间: 2024-10-18 00:54:49

hdu 5410 CRB and His Birthday(混合背包)的相关文章

hdu 5410 CRB and His Birthday 01背包和完全背包

#include<stdio.h> #include<string.h> #include<vector> #include<queue> #include<algorithm> using namespace std; int main() { int _,i,j,m,n,k,a[1024],b[1024],w[1024],dp[2048]; scanf("%d\n",&_); while(_--) { scanf(

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

题意:有n种商品,每种商品中有a个糖果,如果买这种商品就送多b个糖果,只有第一次买的时候才送.现在有m元,最多能买多少糖果? 思路:第一次买一种商品时有送糖果,对这一次进行一次01背包,也就是只能买一次.然后对这种商品来一次完全背包,此时不送糖果,也可以多买. 1 #include <bits/stdc++.h> 2 #define pii pair<int,int> 3 #define INF 0x7f7f7f7f 4 #define LL long long 5 using n

HDU 5410 CRB and His Birthday ——(完全背包变形)

对于每个物品,如果购买,价值为A[i]*x+B[i]的背包问题. 先写了一发是WA的= =.代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <set> 5 using namespace std; 6 typedef pair<int,int> pii; 7 8 pii dp[2005]; 9 int w[1005],A[1005

HDU 5410 CRB and His Birthday

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5410 Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son.She went to the nearest shop with M Won(currency unit).At the shop, there are N kinds of presents

hdu 5410 CRB and His Birthday(动态规划)

题目: CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 748    Accepted Submission(s): 395 Problem Description Today is CRB's birthday. His mom decided to buy many presents for

HDOJ 5410 CRB and His Birthday DP背包

先跑一遍01背包,再跑一遍多重背包 CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 327    Accepted Submission(s): 177 Problem Description Today is CRB's birthday. His mom decided to buy man

HDU 5410 CRB and His Birthday(DP)

CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 83    Accepted Submission(s): 45 Problem Description Today is CRB's birthday. His mom decided to buy many presents for her l

HDU 5410 CRB and His Birthday (2015年多校比赛第10场)

1.题目描述:点击打开链接 2.解题思路:本题是完全背包问题的一种变形.根据题意描述,每种物品的价值随着A[i]是线性变化的,但是并不随着B[i]线性变化,B[i]仅仅是在第一次挑选第i件物品是才算入,其他时候均不算入.因此,这里的状态要比普通的完全背包增加一个维度:是否是第一次选第i件物品,即用(i,j,flag)表示当前背包容量为j时,是否为第一次选第i件物品时的最大价值.那么不难得到如下状态转移方程: dp(i+1,j,0)=max{dp(i,j,0),dp(i,j,1)}; dp(i+1

HDU 5410(2015多校10)-CRB and His Birthday(完全背包)

题目地址:HDU 5410 题意:有M元钱,N种礼物,若第i种礼物买x件的话,会有Ai*x+Bi颗糖果,现给出每种礼物的单价.Ai值与Bi值,问最多能拿到多少颗糖果. 思路:完全背包问题. dp[j][1]在当前物品时花钱为j的并且买过当前物品的最大值. dp[j][0]不买当前这件物品此前花钱为j的的最大值. 每种物品的价值随Ai线性变化,但是不随B[i]线性变化,B[i]仅是在第一次挑选第i件物品是才算入,其他时候均不算入.所以我们可以写出状态转移方程: dp[j][0]=max(dp[j]