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 ?>