POJ 1014 Dividing【多重背包+二进制优化】

本文针对一组具有不同价值的物品,探讨如何将其分为两组且每组价值相等的问题。通过多重背包问题的解决思路,利用01背包问题的二进制优化方法实现,确保所有物品都能被充分利用。

大意:

价值1, 2, 3, ……, 6的物品分别a1, a2, ……, a5, a6件

问能否把这些物品分成两份,使其具有相同的价值(所有物品必须全部用上)

 

分析:

给个物品有多件,即多重背包

只要看能不能将这些物品拼成   总价值 的 一半就可以了

转化为01背包是用二进制优化,否则会超时

 

代码:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int maxn = 20005 * 6;
 7 
 8 int n, all;
 9 int vo[maxn];
10 int dp[maxn];
11 bool solve() {
12     if(all % 2 == 1) return false;
13     all /= 2;
14     memset(dp, 0, sizeof(dp));
15     for(int i = 1; i <= n; i++) {
16         if(vo[i] > all) return false;
17         for(int j = all; j >= vo[i]; j--) {
18             dp[j] = max(dp[j], dp[j - vo[i]] + vo[i]);
19         }
20     }
21     if(dp[all] != all) return false;
22     return true;
23 }
24 
25 int main() {
26     int a[10];
27     int kase = 1;
28     while(scanf("%d %d %d %d %d %d",&a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) ) {
29         all = 0;
30         for(int i = 1; i <= 6; i++) {
31             all += a[i] * i;
32         }
33         if(all == 0) break;
34         n = 1;
35         for(int i = 1; i <= 6; i++) {
36             for(int k = 1; k <= a[i]; k *= 2) {
37                 vo[n++] = k * i;
38                 a[i] -= k;
39             }
40             if(a[i]) vo[n++] = a[i] * i;
41         }
42         n--;
43         printf("Collection #%d:\n", kase++);
44         puts(solve() ? "Can be divided." : "Can't be divided.");
45         puts("");
46     }
47     return 0;
48 }
View Code

 

转载于:https://www.cnblogs.com/zhanzhao/p/3942748.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值