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 }
时间: 2024-10-04 15:05:00

hdoj1171 Big Event in HDU(01背包 || 多重背包)的相关文章

杭电1171 Big Event in HDU(母函数+多重背包解法)

Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23728    Accepted Submission(s): 8363 Problem Description Nowadays, we all know that Computer College is the biggest department

HDU 1059 Dividing(多重背包)

HDU 1059 Dividing(多重背包) http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意: 现在有价值为1,2,3,4,5,6的6种物品, 它们的数量为num[i]( 1<=i<=6 )个. 现在要问的是能否把所有的的物品分成两份且这两份物品的价值总和相同 ? 分析: 首先我们求出所有物品的价值和sum_val, 如果sum_val是奇数, 那么明显不能分. 那么sum_val为偶时, 我们令m=sum_val/2. 我能只要看看从所有

hdu 2191(多重背包)

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14758    Accepted Submission(s): 6229 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

HDU2191_悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(背包/多重背包)

解题报告 题目传送门 题意: 中文不多说; 思路: 基础多重背包,每个物品有多个可以选,转换成01背包解. #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i,j,n,m,v,p,h,cc,w[1010],c[1010],dp[1010]; scanf("%d",&

(hdu step 3.3.1)Big Event in HDU(01背包:N件物品放在容量为V的背包中,第i件物品的费用是c[i],价值是w[i]。问所能获取的最大价值)

Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 854 Accepted Submission(s): 345 Problem Description Nowadays, we all know that Computer College is the biggest department in HDU.

HUD 1171 Big Event in HDU(01背包)

Big Event in HDU Problem Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.The splitting is

HDU 1171 Big Event in HDU(01背包)

Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 31928    Accepted Submission(s): 11169 Problem Description Nowadays, we all know that Computer College is the biggest departmen

hdu(1059) Dividing(多重背包)

题意:输入六个数,价值分别为1——6,输入的数代表该价值的物品的个数:求能否平均分. key:如果奇数肯定不能分,直接输出答案.偶数的话,就是多重背包问题. 试过两种做法,第一种是背包九讲的二进制优化,写三个函数,分别是bag01, bagall, bagmulti~第二种是直接多重背包,但很可能tle,这题我交的就是tle了~ #include <iostream> #include <algorithm> #include <string.h> #include &

【动态规划】背包问题(一) 01背包 完全背包 多重背包

一.01背包 有N件物品和一个容量为V的背包.第i件物品的价格(即体积,下同)是w[i],价值是c[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 这是最基础的背包问题,总的来说就是:选还是不选,这是个问题<( ̄ˇ ̄)/ 相当于用f[i][j]表示前i个背包装入容量为v的背包中所可以获得的最大价值. 对于一个物品,只有两种情况 情况一: 第i件不放进去,这时所得价值为:f[i-1][v] 情况二: 第i件放进去,这时所得价值为:f[i-1][v-c[i]]+w