uvalive5810 uva12368 Candles

题意:每组数据给出n个数,每个数在1-100,问组成这些数的蜡烛的权值的最小值。权值=把选的蜡烛从大到小排列组成的数

组成方式:比如有1 3两个蜡烛 可以组成13(1和3)或4(1+3) 只有一个加号可以用

解:位运算记录状态,can[i][j]表示在i的二进制所记录的状态下能不能组成j

can直接预处理出来,分类讨论 用一个数表示 还是用两个数表示 check的时候都在100以内 直接枚举

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 
 6 using namespace std;
 7 
 8 int n;
 9 bool can[1024][101];
10 int a[11];
11 int cas=0;
12 
13 bool check1(int x,int y,int z){
14     int cnt[11];
15     memset(cnt,0,sizeof(cnt));
16     int tmp=y;
17     while (tmp!=0){
18             int now=tmp%10;
19             tmp=tmp/10;
20             if (((x&(1<<now))==0)||(cnt[now]>0)) return false;
21             cnt[now]++;
22     }
23     tmp=z;
24     while (tmp!=0){
25             int now=tmp%10;
26             tmp=tmp/10;
27             if (((x&(1<<now))==0)||(cnt[now]>0)) return false;
28             cnt[now]++;
29     }
30     return true;
31 }
32 
33 bool check(int x,int y){
34     if ((y<10)&&(x&(1<<y))) return true;
35     for (int i=1;i<=y/2;i++){
36             if (i!=(y-i)){
37                     if (check1(x,i,y-i)) return true;
38             }
39     }
40     if (y==100) return false;
41     int tmpy1=y/10;
42     int tmpy2=y%10;
43     if (tmpy1==tmpy2) return false;
44     if ((x&(1<<tmpy1))==0) return false;
45     if ((x&(1<<tmpy2))==0) return false;
46     return true;
47 }
48 
49 int main(){
50     memset(can,0,sizeof(can));
51     for (int i=1;i<1024;i++){
52             for (int j=1;j<=100;j++) can[i][j]=check(i,j);
53     }
54     while (1){
55             scanf("%d",&n);
56             if (n==0) return 0;
57             cas++;
58             bool flag;
59             int ans=0;
60             for (int i=1;i<=n;i++) scanf("%d",&a[i]);
61             for (int i=1;i<1024;i++){
62                     flag=true;
63                     for (int j=1;j<=n;j++) if (!can[i][a[j]]) flag=false;
64                     if (flag){
65                             int tmp=0;
66                             for (int j=9;j>=0;j--) if (i&(1<<j)) tmp=tmp*10+j;
67                             if ((ans==0)||(ans>tmp)) ans=tmp;
68                     }
69             }
70             printf("Case %d: %d
",cas,ans);
71     }
72     return 0;
73 }
74 /*
75 2 10 11
76 1 30
77 0
78 */
79   
原文地址:https://www.cnblogs.com/baby-mouse/p/4296298.html