hdoj1171 Big Event in HDU(01背包 || 多重背包)
2017-12-09 22:41
387 查看
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1171
题意
老师有一个属性:价值(value)。在学院里的老师共有n种价值,每一种价值value对应着m个老师,说明这m个老师的价值都为value。现在要将这些老师从人数上平分成两个院系,并且希望平分后两个院系老师的总价值A和B应尽可能地相等,求A和B的值(A>=B)。
思路
由于每种老师的个数是有限的,所以使用多重背包解决。由于测试数据不是很严格,所以使用01背包也可以通过。
代码
01背包:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 5010; const int M = 50 * 5000; int v ; int dp[M]; int main() { //freopen("hdoj1171.txt", "r", stdin); int n; while (cin >> n && n >= 0) { int cur = 0; //记录教师总数 int sum = 0; //记录教师总价值 for (int i = 0;i < n; i++) { int val, m; cin >> val >> m; for (int j = 0; j < m; j++) { v[cur++] = val; sum += val; } } memset(dp, 0, sizeof(dp)); for (int i = 0; i < cur; i++) { for (int j = sum / 2; j >= v[i]; j--) dp[j] = max(dp[j], dp[j - v[i]] + v[i]); //weight和value相同 } //由于dp[sum/2]<sum/2,所以dp[sum/2]一定是较小者,sum - dp[sum / 2]是较大者 cout << sum - dp[sum / 2] << " " << dp[sum / 2] << endl; } return 0;
多重背包:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 110; const int M = 50 * 5000; int v , num ; int dp[M]; int sum; void zero_one_pack(int weight, int value, int capacity) { for (int i = capacity; i >= weight; i--) //逆序 dp[i] = max(dp[i], dp[i - weight] + value); } void complete_pack(int weight, int value, int capacity) { for (int i = weight; i <= capacity; i++) //正序 dp[i] = max(dp[i], dp[i - weight] + value); } void mutiple_pack(int weight, int value, int amount, int capacity) { if (weight*amount >= capacity) complete_pack(weight, value, capacity); else { int k = 1; while (k <= amount) { zero_one_pack(weight*k, value*k, capacity); amount -= k; k *= 2; } zero_one_pack(weight*amount, value*amount, capacity); } } int main() { //freopen("hdoj1171.txt", "r", stdin); int n; while (cin >> n && n >= 0) { sum = 0; for (int i = 1; i <= n; i++) { cin >> v[i] >> num[i]; sum += v[i] * num[i]; } memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) mutiple_pack(v[i], v[i], num[i], sum / 2); cout << sum - dp[sum / 2] << " " << dp[sum / 2] << endl; } }
相关文章推荐
- HDU - 1171 Big Event in HDU —— 多重背包转01背包
- HDU 1171 Big Event in HDU 多重背包01求解
- hdoj 1171 Big Event in HDU(母函数/多重背包)
- HDU-1171 - Big Event in HDU - 01背包
- HDOJ-1171 Big Event in HDU(多重背包/母函数)
- HDU/HDOJ 1171 Big Event in HDU 01背包、多重背包、母函数
- hdu 1171 Big Event in HDU(01背包变形)
- HDOJ 1171 Big Event in HDU (多重背包) / (母函数)
- 暑期dp46道(32)--hdoj 1171 Big Event in HDU 多重背包:
- HDOJ 1171 Big Event in HDU(二进制拆分+0 1背包)
- HDU 1171 Big Event in HDU (由01背包演变的水题)
- HDU 1171 Big Event in HDU……(01背包 + 思维)
- [HDOJ 1171] Big Event in HDU 【完全背包】
- hdoj 1171 Big Event in HDU(背包dp+母函数)
- Big Event in HDU (HDU_1171) 01背包
- hdoj-1171-Big Event in HDU
- hdu 1171 Big Event in HDU 多重背包
- hud 1171 Big Event in HDU(基础0_1背包)
- HDU 1171 Big Event in HDU 多重背包
- hdu 1171 Big Event in HDU 背包/动态规划