码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5410 CRB and His Birthday

时间:2015-08-21 23:07:24      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:

本题其实是经典(完全)背包问题的一个变种,只不过需要处理一下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 }
View Code

 

 

 

 

 

hdu5410 CRB and His Birthday

标签:

原文地址:http://www.cnblogs.com/astoninfer/p/4749051.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!