poj1014--Dividing--多重背包

Description

每次给你6种商品的数量,第1种商品的价值为1,第2种商品价值为2……第6种商品价值为6。

问能否将商品分成两堆,使得既不拆分商品,且两堆的价值和相等。

Sample Input

1 0 1 2 0 0
1 0 0 0 1 1
0 0 0 0 0 0

Sample Output

Collection #1:
Can't be divided.

Collection #2:
Can be divided.

题解:

  又是多重背包qwq,刷了一早上水题了。写的时候没有把冒号加上……WA了好几次,感觉自己傻fufu的qwq

  既然让分成两堆,还不让拆开,那么首先我们就知道,如果所有商品的价值和为奇数或0,是永远分不出来的。

  其次思考如何转化为背包问题:将容量设为总价值和的一半,然后照常做多重背包,如果能刚好拼出来总价值和的一半,就输出Can;如果不能刚好拼出来,那就输出Can‘t

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

 

posted @ 2017-09-01 10:15  BK-Edwina  阅读(276)  评论(0编辑  收藏  举报