算法20-----卡诺兰数

1、卡诺兰概念:

卡诺兰数列的递推关系:h(n)= h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2),这是n阶递推关系;

数列的通项:F(n)=C(2n,n)/(n+1)

2、可以解决的问题:

参考链接:https://www.cnblogs.com/yaoyueduzhen/p/5456490.html

1、n个元素的二叉查找树有多少种。
2、n*n棋盘从左下角走到右上角而不穿过主对角线的走法。
3、2n个人排队买票问题,票价50,n个人拿50元,n个人拿100元,售票处无零钱,能顺利卖票的所有排队方式。
4、n个元素全部入栈并且全部出栈的所有可能顺序。

5、矩阵链所有乘法顺序问题(同问题1)。
6、凸多边形剖分成三角形的方法数(同问题1)。

https://www.jianshu.com/p/26925a2fc5e7

3、答案:

这些问题的答案都是卡特兰数F(n)。但是很明显可以看出后三个问题是同质的。
都可以抽象成2n个操作组成的操作链,其中A操作和B操作各n个,且要求截断到操作链的任何位置都有:A操作(向右走一步、收到50元、元素入栈)的个数不少于B操作(向上走一步、收到100元找出50元、元素出栈)的个数。故问题2、3、4其实是同一个问题。

前几项为1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796。

4、算法:

        #采用卡诺兰数通解来求解
        if n<=1:
            return 1
        elif n>=2:
            m=reduce(lambda x,y:x*y,[i for i in range(n+2,2*n+1)])
            n=reduce(lambda x,y:x*y,[j for j in range(1,n+1)])
            return m/n
        #采用数列递推关系来求解,递归求解,超出时间限制
        if n<=1:
            return 1
        res=0
        for i in range(1,n+1):
            res+=self.numTrees(i-1)*self.numTrees(n-i)
        return res
        #采用数列递推关系来求解,循环求解
        if n<=1:
            return 1
        res=[1]*(n+1)
        for i in range(2,n+1):
            count=0
            for j in range(0,i):
                count+=res[j]*res[i-j-1]
            res[i]=count
        return res[n]
原文地址:https://www.cnblogs.com/Lee-yl/p/9210652.html