POJ 1014 Dividing(多重背包+二进制优化)

http://poj.org/problem?id=1014

题意:
6个物品,每个物品都有其价值和数量,判断是否能价值平分。

思路:

多重背包。利用二进制来转化成0-1背包求解。

 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 70000;
 9 int sum;
10 int a[7];
11 int d[maxn];
12 int w[maxn];
13 
14 int main()
15 {
16     //freopen("D:\txt.txt", "r", stdin);
17     int kase = 0;
18     while (scanf("%d", &a[1]))
19     {
20         for (int i = 2; i <= 6; i++)
21             scanf("%d", &a[i]);
22         sum = 0;
23         for (int i = 1; i <= 6; i++)
24             sum += i*a[i];
25         if (sum == 0)  break;
26 
27         printf("Collection #%d:
", ++kase);
28 
29         if (sum % 2)
30         {
31             printf("Can't be divided.

");
32             continue;
33         }
34         int count = 0;
35         for (int i = 1; i <= 6; i++)
36         {
37             int m = a[i];
38             int k = 1;
39             while (k < m)
40             {
41                 w[count++] = k*i;
42                 m -= k;
43                 k *= 2;
44             }
45             w[count++] = m*i;
46         }
47         sum = sum / 2;
48         memset(d, 0, sizeof(d));
49         for (int i = 0; i < count; i++)
50         {
51             for (int j = sum; j >= w[i]; j--)
52                 d[j] = max(d[j], d[j - w[i]] + w[i]);
53         }
54         if (d[sum]==sum)
55             printf("Can be divided.

");
56         else
57             printf("Can't be divided.

");
58     }
59 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6565746.html