HDU 1059 Dividing

 

题意:有6种大理石(marble,怀疑是不是大理石的意思。。。几块大理石也值得争?!),每种若干件且每种大理石有一定的价值(分别为1,2,3,4,5,6)。问能否分成价值相等的两份。

分析:多重背包。价值和费用相同。注意初始化。以下有两种解法。。。

 

代码1(多重背包):

 

 

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int f[60005],num[7];
 5 int sum,half;
 6 const int INF=0x3f3f3f3f;
 7 
 8 int max(int a,int b){
 9     return a>b?a:b;
10 }
11 
12 void ZeroOnePack(int c){
13     int i;
14     for(i=half;i>=c;i--)
15         f[i]=max(f[i],f[i-c]+c);
16 }
17 
18 void CompletePack(int c){
19     int i;
20     for(i=c;i<=half;i++)
21         f[i]=max(f[i],f[i-c]+c);
22 }
23 
24 int main()
25 {
26     //freopen("in.txt","r",stdin);
27     int i,j,k,cas=1;
28     while(1){
29         for(i=1,sum=0;i<=6;i++){
30             scanf("%d",&num[i]);
31             sum+=num[i]*i;
32         }
33         if(sum==0) break;
34         if(sum%2){
35             printf("Collection #%d:\n",cas++);
36             printf("Can't be divided.\n\n");
37             continue;
38         }
39         half=sum/2;
40         f[0]=0;
41         for(i=1;i<=half;i++)
42             f[i]=-INF;
43         for(i=k=1;i<=6;i++){
44             if(i*num[i]>=half)
45                 CompletePack(i);
46             else{
47                 while(k<num[i]){
48                     ZeroOnePack(k*i);
49                     num[i]-=k;
50                     k<<=1;
51                 }
52                 ZeroOnePack(num[i]*i);
53             }
54         }
55         printf("Collection #%d:\n",cas++);
56         if(f[half]==half) printf("Can be divided.\n\n");
57         else              printf("Can't be divided.\n\n");
58     }
59     return 0;
60 }

 

代码2(可行性解法):

 

 

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int f[7][60005],num[7];
 5 int sum,half;
 6 
 7 int max(int a,int b){
 8     return a>b?a:b;
 9 }
10 
11 int main()
12 {
13     //freopen("in.txt","r",stdin);
14     int i,j,cas=1;
15     while(1){
16         for(i=1,sum=0;i<=6;i++){
17             scanf("%d",&num[i]);
18             sum+=num[i]*i;
19         }
20         if(sum==0) break;
21         if(sum%2){
22             printf("Collection #%d:\nCan't be divided.\n\n",cas++);
23             continue;
24         }
25         half=sum/2;
26         f[0][0]=0;
27         for(i=1;i<=half;i++)
28             f[0][i]=-1;
29         for(i=1;i<=6;i++){
30             for(j=0;j<=half;j++)
31                 if(f[i-1][j]>=0)
32                     f[i][j]=num[i];
33                 else f[i][j]=-1;
34             for(j=0;j<=half-i;j++)
35                 if(f[i][j]>0)
36                     f[i][j+i]=max(f[i][j+i],f[i][j]-1);
37         }
38         printf("Collection #%d:\n",cas++);
39         if(f[6][half]>=0) printf("Can be divided.\n\n");
40         else              printf("Can't be divided.\n\n");
41     }
42     return 0;
43 }

 

 

posted on 2013-03-04 23:25  Acmer_Roney  阅读(163)  评论(0编辑  收藏  举报

导航