hdu5410 CRB and His Birthday

本题其实是经典(完全)背包问题的一个变种,只不过需要处理一下B[i]。

设dp[i]为花费i所得糖果最大值。

根据题目,共有n堆礼物,买k个第i堆礼物获得糖果A[i] * k + B[i] (k > 0),每堆礼物数不限。

我们可以把每一堆礼物中的每一个礼物单独看成一堆。那么一共有无穷堆共k组礼物。

belong[i] = i % n代表现在的第i堆糖果原来属于哪一堆。

这样理论上下面的代码可以求解:

1 int solve(){
2   for(int i = 0; ; i++){
3     int k = i % n;
4     for(int j = m; j >= W[k]; j--){
5       dp[j] = max(dp[j], dp[j -W[i]] + A[k] + (i < n ? B[k] : 0));
6     }
7   }
8   return ans = dp[m];
9 }

这个应该比较直观,容易理解。

那么下面把这个循环改成两部分。

第一部分单独考虑取第一轮dp(原来每堆糖果各拿出一个)。

1 for(int i = 0; i < n; i++){
2   for(int j = m; j >= W[i]; j--){
3     dp[i] = max(dp[j], dp[j - W[i]] + A[i] + B[i]);
4   }
5 }

第二部分仍然是完全背包。

1 for(int i = 1; i <= m; i++){
2   for(int j = 0; j < n; j++){
3     if(i >= W[j]) dp[i] = max(dp[i], dp[i - W[j]] + A[j]);
4   }
5 }

这样就可得出答案了。

代码中的第二轮循环后面注释代码也是可行的。

acm.hdu.edu.cn/showproblem.php?pid=5410

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4
 5 using namespace std;
 6
 7 const int maxn = 1e3 + 10;
 8 int dp[maxn * 2];
 9 int w[maxn], a[maxn], b[maxn];
10 int n, m;
11
12 void solve(){
13     memset(dp, 0, sizeof dp);
14     //preprocessing:: 0-1 packing
15     for(int i = 0; i < n; i++){
16         for(int j = m; j >= w[i]; j--){
17             dp[j] = max(dp[j], dp[j - w[i]] + a[i] + b[i]);
18         }
19     }
20     //full packing
21     for(int i = 1; i <= m; i++){
22         for(int j = 0; j < n; j++){
23             if(i >= w[j]) dp[i] = max(dp[i - w[j]] + a[j], dp[i]);
24         }
25     }
26     /*
27     for(int i = 0; i < n; i++){
28         for(int j = w[i]; j <= m; j++){
29             dp[j] = max(dp[j], dp[j - w[i]] + a[i]);
30         }
31     }
32     */
33     printf("%d\n", dp[m]);
34 }
35
36 int main(){
37     //freopen("in.txt", "r", stdin);
38     int T;
39     scanf("%d", &T);
40     while(T--){
41         scanf("%d%d", &m, &n);
42         for(int i = 0; i < n; i++) scanf("%d%d%d", &w[i], &a[i], &b[i]);
43         solve();
44     }
45     return 0;
46 }

 

时间: 2025-01-01 07:31:13

hdu5410 CRB and His Birthday的相关文章

ACM学习历程—HDU5410 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. (

混合背包 hdu5410 CRB and His Birthday

传送门:点击打开链接 题意:你有M块钱,如今有N件商品 第i件商品要Wi块,假设你购买x个这种商品.你将得到Ai*x+Bi个糖果 问能得到的最多的糖果数 思路:很好的一道01背包和全然背包结合的题目 首先,对于第i件商品,假设仅仅买1个,得到的价值是Ai+Bi 假设在买1个的基础上再买.得到的价值就是Ai 也就是说,除了第一次是Ai+Bi.以后购买都是Ai 那么,我们是否能将i商品拆分成两种商品,当中两种商品的代价都是Wi, 第一种的价值是Ai+Bi,可是仅仅同意买一次 另外一种的价值是Ai.能

HDU5410——01背包+完全背包——CRB and His Birthday

http://acm.hdu.edu.cn/showproblem.php?pid=5410 /* 先01背包一下再完全背包一下 */ /************************************************ * Author :Powatr * Created Time :2015-8-20 19:46:35 * File Name :1005_1.cpp ************************************************/ #inclu

hdu5410(2015多校10)--CRB and His Birthday(背包问题)

题目链接:点击打开链接 题目大意:有m块钱,有n种货物,每种货物都有一个wi的价钱,假设买了x个i中货物,会花wi*x的钱,同时老板还会赠送a*x+b的糖果,问怎么样买礼物,可以让糖果数最多. dp[i][j][0]当买到第i种的时候,花钱是j且没有买过i能得到最多的糖果数. dp[i][j][1]当买到第i种的时候,花钱是j且买过i能得到的最多的糖果数. 按照货物数遍历从1到n,那么就可以省略一维,dp[i][0]在当前物品时,花钱为j的不买当前这件物品的最大值,dp[i][1]在当前物品时,

HDOJ 5409 CRB and Graph 无向图缩块

无向图缩块后,以n所在的块为根节点,dp找每块中的最大值. 对于每一个桥的答案为两块中的较小的最大值和较小的最大值加1 CRB and Graph Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 113    Accepted Submission(s): 41 Problem Description A connected, undi

hdu5414 CRB and String

Problem Description CRB has two strings s and t. In each step, CRB can select arbitrary character c of s and insert any character d (d ≠ c) just after it. CRB wants to convert s to t. But is it possible? Input There are multiple test cases. The first

hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)

题目链接:hdu 5412 CRB and Queries 首先对所有出现过的值排序,建立线段树,每个线段树的节点是一棵笛卡尔树,笛卡尔树记录区间下标值. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define lson(x) (x<<1) #define rson(x) ((x<<

ACM学习历程—HDU5407 CRB and Candies(数论)

Problem Description CRB has N different candies. He is going to eat K candies.He wonders how many combinations he can select.Can you answer his question for all K (0 ≤ K ≤ N )?CRB is too hungry to check all of your answers one by one, so he only asks

CRB and His Birthday 01背包 + 多重背包

CRB and His Birthday 题目抽象:背包问题,这里x个物品的价值是a * x + b (x > 0)  or 0 (x = 0). 分析:将物品按购买数量分类  1. 1件,  2 多件(>1).  对于一件的情况是01背包.  对于多件的情况是多重背包. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int dp