1 <?php
 2     #给定入栈序列,求出栈序列组合总数
 3     #这是一个catalan数问题
 4     #设共有n个数入栈,将入栈序列和出栈序列写在一起共有2n个数
 5     #将第一个入栈的数作为基点,则第一个数肯定是在第2i+1的位置出栈
 6     #否则第一个数入栈编号是0,如果是在2i,则在第一个数入栈和出栈之间共有2i-1个数,是奇数
 7     #既然是奇数,则说明有数在第一个数出栈之前入栈却没有出栈,矛盾
 8     #那么,我们可以找到地推规律,设f(2n)表示n个数的入栈出栈序列总数
 9     #则 f(2n) = f(0)f(2n-2) + f(2)f(2n-4) + ... + f(2n-2)f(0)
10     #f(i)f(2n-i-2)表示位于第一个数入栈和出栈之间有i个数,第一个数出栈以后有2n-i+2个数
11     #易知f(2) = 1, f(4) = 2 ...
12 
13     #n代表共有n个元素入栈
14     function count_pop($n) {
15         #如果只有一个或0个元素,则出栈序列只有一种
16         if ($n <= 1) return 1;
17         $sum = 0;
18         for ($i = 0; $i < $n; $i++) {
19             $sum += count_pop($i) * count_pop($n - 1 - $i); 
20         }
21 
22         return $sum;
23     }
24 
25     echo count_pop(4);
26 
27     #括号配对问题
28     #问n对括号最多有多少种配对方法
29     #例如2对括号的配对方法有()(),(())共两种
30     #这也是一个catalan数列问题
31     #以第一个做括号为基点a,出现的位置为1,则下一个于这个括号配对的肯定是2i+1,原理与上同
32     #用f(n)表示共有n对括号,那么
33     #f(n) = f(0)f(n-1) + f(1)f(n-2) + ... + f(n-1)f(0)
34     #其中f(i)f(n-1-i)表示第一对左右括号之间共有i对括号配对,第一对左右括号右边共有n-1-i对括号配对
35     #程序和上面一模一样
36 
37     #再来就是剧院买票问题
38     #有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票
39     #剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零
40     #将持5元买票的人视为左括号,10元的人视为右括号,问题解决
41 
42     #然后是n个节点,可以构成多少种不同形态的二叉树,
43     #   1            2 
44     #  / \    和    / \   算是形态相同
45     # 2   3        1   3
46     #   1            2 
47     #  / \    和    /     算是形态不同
48     # 2   3        1   
49     #             /
50     #            3
51 
52     #同样是catalan数问题,设f(n)为n个节点的树形态
53     #则f(n) = f(0)f(n-1) + f(1)f(n-2) + ... + f(n-1)f(0)
54     #f(i)f(n-1-i)表示当前树的左子节点共有i个,右子节点共有n-i-1个
55     #问题同上,解决
56 ?>
posted on 2012-10-08 00:14  ZimZz  阅读(269)  评论(0编辑  收藏  举报