hdoj2191 珍惜现在,感恩生活(01背包 || 多重背包)

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=2191

思路

由于每种大米可能不止一袋,所以是多重背包问题,可以直接使用解决多重背包问题的方法,也可以将多重背包转化为01背包后求解。

代码

01背包:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int N = 100 * 20 + 10;
 8 int m[N], w[N];    //记录每袋大米的价格、重量
 9 int dp[N];
10 
11 int main()
12 {
13     //freopen("hdoj2191.txt", "r", stdin);
14     int t;
15     cin >> t;
16     while (t--)
17     {
18         int n, k;
19         cin >> n >> k;
20         int cnt = 0;    //共有cnt袋大米
21         for (int i = 0; i < k; i++)
22         {
23             int p, h, c;
24             cin >> p >> h >> c;
25             for (int j = 0; j < c; j++)
26             {
27                 m[cnt] = p;
28                 w[cnt] = h;
29                 cnt++;
30             }
31         }
32 
33         memset(dp, 0, sizeof(dp));
34         for (int i = 0; i < cnt; i++)
35         {
36             for (int j = n; j >= m[i]; j--)
37                 dp[j] = max(dp[j], dp[j - m[i]] + w[i]);
38         }
39         cout << dp[n] << endl;
40     }
41     return 0;
42 }

多重背包:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int N = 20 * 100 + 10;
 8 int m[N], w[N], num[N];
 9 int dp[N];
10 
11 void zero_one_pack(int weight, int value, int capacity)
12 {
13     for (int i = capacity; i >= weight; i--)    //逆序
14         dp[i] = max(dp[i], dp[i - weight] + value);
15 }
16 
17 void complete_pack(int weight, int value, int capacity)
18 {
19     for (int i = weight; i <= capacity; i++)    //正序
20         dp[i] = max(dp[i], dp[i - weight] + value);
21 }
22 
23 void multiple_pack(int weight, int value, int amount, int capacity)
24 {
25     if (weight*amount >= capacity)
26         complete_pack(weight, value, capacity);
27     else
28     {
29         int k = 1;
30         while (k <= amount)
31         {
32             zero_one_pack(weight*k, value*k, capacity);
33             amount -= k;
34             k *= 2;
35         }
36         zero_one_pack(weight*amount, value*amount, capacity);
37     }
38 
39 }
40 
41 int main()
42 {
43     //freopen("hdoj2191.txt", "r", stdin);
44     int t;
45     cin >> t;
46     while (t--)
47     {
48         int n, k;
49         cin >> n >> k;
50         for (int i = 0; i < k; i++)
51             cin >> m[i] >> w[i] >> num[i];
52 
53         memset(dp, 0, sizeof(dp));
54         for (int i = 0; i < n; i++)
55             multiple_pack(m[i], w[i], num[i], n);
56         cout << dp[n] << endl;
57     }
58     return 0;
59 }

 

posted @ 2017-12-11 16:54  ColdCode  阅读(232)  评论(0编辑  收藏  举报
AmazingCounters.com