hdoj1171 Big Event in HDU(01背包 || 多重背包)

Posted ColdCode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdoj1171 Big Event in HDU(01背包 || 多重背包)相关的知识,希望对你有一定的参考价值。

题目链接

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

题意

老师有一个属性:价值(value)。在学院里的老师共有n种价值,每一种价值value对应着m个老师,说明这m个老师的价值都为value。现在要将这些老师从人数上平分成两个院系,并且希望平分后两个院系老师的总价值A和B应尽可能地相等,求A和B的值(A>=B)。

思路

由于每种老师的个数是有限的,所以使用多重背包解决。由于测试数据不是很严格,所以使用01背包也可以通过。

代码

01背包:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int N = 5010;
 8 const int M = 50 * 5000;
 9 int v[N];
10 int dp[M];
11 
12 int main()
13 {
14     //freopen("hdoj1171.txt", "r", stdin);
15     int n;
16     while (cin >> n && n >= 0)
17     {
18         int cur = 0;    //记录教师总数
19         int sum = 0;    //记录教师总价值
20         for (int i = 0;i < n; i++)
21         {
22             int val, m;
23             cin >> val >> m;
24             for (int j = 0; j < m; j++)
25             {
26                 v[cur++] = val;
27                 sum += val;
28             }
29         }
30 
31         memset(dp, 0, sizeof(dp));
32         for (int i = 0; i < cur; i++)
33         {
34             for (int j = sum / 2; j >= v[i]; j--)
35                 dp[j] = max(dp[j], dp[j - v[i]] + v[i]);    //weight和value相同
36         }
37         //由于dp[sum/2]<sum/2,所以dp[sum/2]一定是较小者,sum - dp[sum / 2]是较大者
38         cout << sum - dp[sum / 2] << " " << dp[sum / 2] << endl;
39     }
40     return 0;
41 

多重背包:

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

 

以上是关于hdoj1171 Big Event in HDU(01背包 || 多重背包)的主要内容,如果未能解决你的问题,请参考以下文章

01背包HDU 1171 Big Event in HDU

HDU-1171 Big Event in HDU (多重背包)

HDU 1171 Big Event in HDU(多重背包)

HUD 1171 Big Event in HDU(01背包)

Hdu 1171Big Event in HDU

hdu 1171 Big Event in HDU