PHP Catalan数的几个应用

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

你可能感兴趣的:(PHP)