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 }
本站使用「CC BY-NC-SA」创作共享协议,转载请在文章明显位置注明作者及出处。