高矮不同的人排队问题

12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? (Java版)

思路: 从网上看了半天人家的分析,终于看明白了,在这里记录一下自己的思路

先用一组数来代表这12个人, 1,2,3,4,5,6 7,8,9,10,11,12  排成两排,每排要递增排列,且对应位置第二排要大于第一排,则可以是

1 2 3  4  5    6       =>   第一排的数用0来表示,第二排的数用1来表示,则这个数组序列就是 000000 111111

7 8 9 10 11 12

也可以是

1 3 5 7  9  11    =>  这个数组序列就是010101 010101

2 4 6 8 10 12

 

所以对于任意排序 只要有对应的0和1的序列就可以, 就是有一个0就必须对应的有一个1,

比如 000111000111就可以 对应的排队是 123789  - 456 10 11 12 , 但是有个条件需要满足,就是序列是递增,且第二排要大于第一排

这样问题其实转化为了求12个数的所有可能得入栈和出栈顺序,0代表入栈,1代表出栈

 

解决方案:首先12个数可以构成所有的0和1的组合是1<<12-1 = 4095, 我们需要依次遍历这4095个数,对于每个数的二进制表示,我们首先需要知道是否满足上述的条件,即肯定要出现六个1, 然后对满足含有六个1的数,对其分成两组,第一组是左侧的六位,第二组是右侧的六位,如果第二组的每个位置的数都大于第一组,则这个数就是我们要找的

 

 1 void catalan(){
 2         int num;
 3         int[] front = new int[6];
 4         int[] back = new int[6];
 5         int counter = 0;
 6         int i, j , k;
 7         for(num = 0; num < (1<<12); num++){
 8             //是否含有六个1?
 9             if(bitCount(num) == 6){
10                 i = j = 0;
11                 
12                 for(k = 11; k >=0; k--){
13                     //填充前后排
14                     if((num & (1<<k)) == 0){
15                         //从左到右扫描num,如果碰见的是0,即num&(1<<k)==0,则填充前排对应的位置
16                         //因为我们要从右到左扫描num,所以k是从11开始,这样的话1<<11才能落在num的最高位
17                         front[i++] = 11-k;
18                     }else{
19                         //如果碰见的不是是0,即num&(1<<k)!=0,则填充后排对应的位置
20                         back[j++] = 11-k;
21                     }
22                 }
23                 boolean ok = true;
24                 //前后排填充完毕,开始判断是否符合前排要低于后排的条件
25                 for(int m = 0; m < 6; m++){
26                     if(front[m] > back[m]){
27                         ok = false;
28                         break;
29                     }
30                 }
31                 
32                 if(ok){
33                     logBin(num);
34                     counter++;
35                 }
36             }
37         }
38         
39         System.out.println("TOTAL: " + counter);
40     }
41     
42     private int bitCount(int n){
43         int counter = 0;
44         while(n>0){
45             n &= (n-1);
46             counter++;
47         }
48         return counter;
49     }
50     
51     private void logBin(int n){
52         System.out.println(Integer.toBinaryString(n));
53     }

参考: http://blog.csdn.net/hackbuteer1/article/details/7450250

posted @ 2015-12-09 10:47  蟹粉小笼包  阅读(1171)  评论(0编辑  收藏  举报