12个高矮不同的人,排成两排,逐步推导卡特兰数(Catalan)

题目描述:12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

本文将基于两个「等价问题」,逐步推导至「卡特兰数」

等价问题一

  • 由 6 个 0 和 6 个 1 组成一个 12 位的二进制数,要求从左到右扫描,使得任意位置 0 的累计数都不小于 1 的累计数,求满足条件的组合有多少种。

证明

将12个人以 A, B, C, … F, L从低到高标记。并将第一排位置标为 0,第二排位置标为 1。如下图:

以 A - L 的顺序开始选择位置,根据选择顺序,得到一个由 6 个 0 和 6 个 1 组成的二进制数。不难发现,为了满足「每排必须是从矮到高排列, 而且第二排比对应的第一排的人高」,生成的二进制数在任意位置 0 的累计数都必须大于或等于 1 的累计数

基于此将问题转换为「等价问题一」:由 6 个 0 和 6 个 1 组成一个 12 位的二进制数,要求从左到右扫描,使得任意位置 0 的累计数都不小于 1 的累计数,求满足条件的组合有多少种

选位置

等价问题二

  • 6 个元素进出栈(一次),问不同的出栈顺序有几种?

基于「等价问题一」,我们得到了一个 12 位的二进制数。其中 6 个 0 和 6 个 1,且在任意位置 0 的累计数不小于 1 的累计数。

0 当做「入栈」,1 当做「出栈」。「0 的累计数在任意位置都不小于 1 的累计数」 好比 「栈内必须有元素才能选择出栈」。

基于此将问题转换为「等价问题二」:6 个元素进出栈(一次),问不同的出栈顺序有几种?

解题思路

基于「等价问题二」,先将问题设为:

  • 有 n 个元素进出栈,问不同的出栈顺序有几种?

设函数 h(n) 为 n 个元素进出栈顺序的解。假设 k (1 <= k <= n) 是最后一个出栈的元素,那么 k 进栈之前栈一定是空的,k 之前的 (k - 1) 个元素的进出栈是独立的 即 h(k - 1)。同理 k 之后的 (h - k) 个元素也是独立的 即 h(n - k)。 根据前后结果,求得当 k 最后一个出栈时结果为:h(k - 1) * h(n - k)。

因为 k 可以是 [1, n] 之间的任意数,所以 h(n) 是累加 k 为 1 - n 的所有结果。即:

  • h(n) = h(0)*h(n-1) + h(1)*h(n-2) + … + h(n-1)*h(0)。

当只有一个元素时,进出栈顺序只有一种。即 h(1) = 1,因为 h(1) = h(0) * h(0),h(0) = 1。

java 代码实现 h(n);将n = 6带入,计算出结果 132。

public static int h(int n){
    if(n == 0 || n == 1){
        return 1;
    }
    int ret = 0;
    for (int i = 0; i < n; i++){
        ret += h(i) * h(n - i -1);
    }
    return ret;
}

参考

  • https://baike.baidu.com/item/%E5%8D%A1%E7%89%B9%E5%85%B0%E6%95%B0/6125746
  • https://blog.youkuaiyun.com/qq_38216239/article/details/78738785
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值