高矮不同的人排队问题

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

时间: 2024-10-20 12:55:36

高矮不同的人排队问题的相关文章

java代码实现:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

此题参考与其他人思路, 2个解题方式. 1. 1 /** 2 * 用java代码实现:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 3 * 状态树方式解 4 * 用状态生成树的方式来做的,先把12个人按从低到高一次编号, 5 * 从(1 ; 2)出发,加入3和4的时候生成(1,3 ; 2,4)和(1,2 ; 3,4), 6 * 然后加入5和6,分别从前面的两个状态出发,可以生成5种状态,就是说6个人时有5种排列 7 * @author

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

#include <iostream> #define DefaultSize 9 //问题描述: //12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? using namespace std; class Grial { public: Grial(int sz=DefaultSize) { visted = new bool [sz]; data = new int [sz]; size = sz; for(int i=1;i<

【编程题目】12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,

80.阿里巴巴一道笔试题(运算.算法)问题描述:12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 我的思路:输入从小到大排列的数字  把数字4个分为一组 如下: min **** B A    **** max 其中第一个数字一定是当前最小的, 最后一个数字一定是当前最大的. 其次,设位置A .B,这样去掉这四个数字, 问题又变成了规模小一些的同样的问题. 关键是A和B的确定,有很多种可能,我们依次尝试,如果不满足问题的条件了,就退出来

致我们终将忘记的算法(随处可见的经典&lt;2&gt;)

********Catalan数********* Catalan数(卡塔兰数)取自组合数学中一个常在各种计数问题出现的数列.卡塔兰数的一般项公式为: 令其为h(n)的话,满足h(n)=h(0)*h(n-1)+h(1)*h(n-2)+......+h(n-1)h(0)  (n>=2).若从中取出的数叫做第n个Catalan数,前几个Catalan数是: 1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,969484

算法笔试

1.把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向.   10  / \  6  14 / \ / \4  8 12 16 转换成双向链表4=6=8=10=12=14=16.  首先我们定义的二元查找树 节点的数据结构如下: struct BSTreeNode{  int m_nValue; // value of node  BSTreeNode *m_pLeft; // left child of

数据结构与算法80道

1. 把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表. 要求不能创建任何新的结点,只调整指针的指向. 10 / \ 6 14 / \ / \ 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16. 首先我们定义的二元查找树 节点的数据结构如下: struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of no

hdu4489(递推dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4489 题意:给一个n,求n个高矮不同的人排成一排使得高.矮依次排列的种数. 详细思路参考:http://blog.csdn.net/bossup/article/details/9915647 这类题都是独立出最后一个再分情况讨论如何排进去. #include <cstdio> #include <cstring> #include <cmath> #include <

算法1

1.把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向.   10  / \  6  14 / \ / \4  8 12 16 转换成双向链表4=6=8=10=12=14=16.  首先我们定义的二元查找树 节点的数据结构如下: struct BSTreeNode{  int m_nValue; // value of node  BSTreeNode *m_pLeft; // left child of

Catalan数——卡特兰数

一.Catalan数的定义 令h(0)=1,h(1)=1,Catalan数满足递归式:h(n) = h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)*h(0)  (n>=2) 该递推关系的解为:h(n) = C(2n,n)/(n+1),n=0,1,2,3,... (其中C(2n,n)表示2n个物品中取n个的组合数) 二.问题描述 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 问题分析: 我们先把这12个