hdu 1059 Dividing 多重背包
2017-09-08 13:02
393 查看
传送门http://acm.hdu.edu.cn/showproblem.php?pid=1059
题意:
给出6个数字a[1]~a[6], a[i]代表价值为i的硬币有多少.
问能否把硬币平均分为两堆.
sum(a[i]) < 5e4 (目测数据不止5e4….?保险起见开了5e5/扶额)
分析
当 sum(a[i]) 为奇数时, 必定不可分
判断体积为sum(a[i])/2的多重背包能否填满即可
设定物品价值和体积相同, 那么如果存在恰好填满的情况, 那么一定是最大价值=背包容量.
多重背包按照二进制拆分为01背包
假设价值为w的物品有n个, 则按照 1, 2, 4, 8, ….., (1^log(n)) 拆分
设sum(1, (1^log(n)) = sum, 设 ret = n - sum;
则有在 (0~sum) 内的所有数p都可以用拆分数的和表示 (二进制表示)
而(sum ~ n) 之间的数可用 p+ret表示
拆分完毕, 0-1背包构建完成.
2017-09-08
题意:
给出6个数字a[1]~a[6], a[i]代表价值为i的硬币有多少.
问能否把硬币平均分为两堆.
sum(a[i]) < 5e4 (目测数据不止5e4….?保险起见开了5e5/扶额)
分析
当 sum(a[i]) 为奇数时, 必定不可分
判断体积为sum(a[i])/2的多重背包能否填满即可
设定物品价值和体积相同, 那么如果存在恰好填满的情况, 那么一定是最大价值=背包容量.
多重背包按照二进制拆分为01背包
假设价值为w的物品有n个, 则按照 1, 2, 4, 8, ….., (1^log(n)) 拆分
设sum(1, (1^log(n)) = sum, 设 ret = n - sum;
则有在 (0~sum) 内的所有数p都可以用拆分数的和表示 (二进制表示)
而(sum ~ n) 之间的数可用 p+ret表示
拆分完毕, 0-1背包构建完成.
#include <stdio.h> #include <iostream> #include <cstring> using namespace std; const int MAX = 2e5+10; const int INF = 2e5+10; int a[7], dp[MAX], sum, T, tmax, tmp; int mmax(int a, int b) { return a > b ? a : b; } bool getin() { bool ret = false; for (int i = 1; i <= 6; ++i) { cin >> a[i]; ret |= a[i]; } memset(dp, 0, sizeof(dp)); sum = 0; return ret; } bool judge() { for (int i = 1; i <= 6; ++i) sum += (i*a[i]); if (sum & 1) return false; sum >>= 1; for (int i = 1; i <= 6; ++i) { if (a[i] == 0) continue; int k; for (k = 1; k < a[i]; a[i] -= k, (k <<= 1)) for (int j = sum, tmp = i*k j >= tmp; --j) { if (dp[j-tmp] + tmp > j) continue; dp[j] = mmax(dp[j], dp[j-tmp] + tmp); } for (int j = sum, tmp = a[i]*i; j >= tmp; --j) { if (dp[j-tmp] + tmp > j) continue; dp[j] = mmax(dp[j], dp[j-tmp] + tmp); } } if (dp[sum] == sum) return true; else return false; } int main() { freopen("out.t", "w", stdout); freopen("in.t", "r", stdin); ios::sync_with_stdio(false); cin.tie(0); for (T = 1; getin(); ++T) { cout << "Collection #" << T << ":" << "\n"; if (judge()) cout << "Can be divided." << "\n\n"; else cout << "Can't be divided." << "\n\n"; } return 0; }
2017-09-08
相关文章推荐
- hdu 1059 Dividing 多重背包
- Dividing (HDU 1059) —— 多重背包
- hdu 1059 Dividing(完全背包)
- (step3.3) hdu 1059(Dividing——多重背包)
- HDU 1059 Dividing 多重背包
- HDU 1059 Dividing 多重背包
- 【日常学习】【多重背包】【二进制优化】hdu1059 Dividing题解
- hdu 1059 Dividing(多重背包)
- hdu——1059——Dividing(多重背包)
- hdu 1059 Dividing 多重背包
- Hdu 1059 Dividing & Zoj 1149 & poj 1014 Dividing(多重背包)
- hdu 1059 Dividing (多重背包)
- HDU 1059 Dividing(多重背包)
- HDU-1059-Dividing-多重背包
- poj1014 hdu1059 Dividing 多重背包
- hdu 1059 Dividing(完全背包)
- HDU 1059 Dividing 多重背包
- HDU1059_Dividing【多重背包】【二进制】
- 【多重背包】HDU 1059 Dividing
- HDU 1059 Dividing(多重背包)