卡特兰数介绍及其应用

定义
组合数学中一个常在各种计数问题中出现的数列,其对应的序列为:C0 = 1,
C1 = 1, C2 = 2, C3 = 5, C4 = 14, C5 = 42,
C6 = 132, C7 = 429, C8 = 1430, C9 = 4862, C10 = 16796,
C11 = 58786, C12 = 208012, C13 = 742900, C14 = 2674440, C15 = 9694845,
C16 = 35357670, C17 = 129644790, C18 = 477638700, C19 = 1767263190, C20 = 6564120420, …

常见适用场景
出栈次序
一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
分析:首先,我们设 f(n)=序列个数为n的出栈序列种数。

假定某个数A第k次出栈,
A出空之前第一个出栈的序数k将1 ~ n的序列分成两个序列:其中一个是1 ~ k-1,序列个数为k-1;另外一个是k+1 ~ n,序列个数是n-k。

此时,我们若把k视为确定一个序数,那么根据乘法原理,f(n)的问题就等价于——序列个数为k-1的出栈序列种数乘以序列个数为n - k的出栈序列种数(一种递归的思想),即选择k这个序数的f(n)= f(k-1)×f(n-k)对k求和。

k可以选1到n,再根据加法原理,将k取不同值的序列种数相加,得到的总序列种数为:f(n)=f(0)f(n−1)+f(1)f(n−2)+……+f(n−1)f(0)f(n)=f(0)f(n−1)+f(1)f(n−2)+……+f(n−1)f(0)

这个公式与卡特兰数的递推式一模一样

推导

最经典的推导方法是利用生成函数法(北大组合数学给出的解法),可以参考这个推导:公示推导

代码计算第二项的数值:

//函数功能: 计算Catalan的第n项
//函数参数: n为项数
//返回值:  第n个Catalan数
int Catalan(int n) {
        if (n <= 1) return 1;
        int[] h = new int[n + 1]; //保存临时结果
        h[0] = h[1] = 1;        //h(0)和h(1)
        for (int i = 2; i <= n; i++)    //依次计算h(2),h(3)...h(n)
        {
            h[i] = 0;
            for (int j = 0; j < i; j++) //根据递归式计算 h(i)= h(0)*h(i-1)+h(1)*h(i-2) + ... + h(i-1)h(0)
                h[i] += (h[j] * h[i - 1 - j]);
        }
        int result = h[n]; //保存结果
        return result;
    }


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值