参考资料

卡特兰数递推公式证明及应用 CSDN博客

卡特兰数 - OI Wiki

定义

构造一个由n个0和n个1的数列,使得任何一个前缀0的个数不少于1的个数的方案数$H_n$即为卡特兰数。

其对应的序列为:

$H_1$$H_2$$H_3$$H_4$$H_5$$H_6$...
1251442132...

公式

$$ H_n = \begin{cases} \sum_{i = 1}^{n}H_{i - 1}H_{n - i} &n \geq2 \\ 1 &n = 0,1 \\ \end{cases} \\ H_n = \binom{2n}{n} - \binom{2n}{n - 1} \\ H_n = \frac{\binom{2n}{n}}{n + 1}(n \geq 2) \\ H_n = \frac{H_{n - 1}(4n - 2)}{n + 1} $$

证明

公式1证明

公式2证明

公式3证明

$$ \begin{align*} \binom{2n}{n} - \binom{2n}{n - 1} &= \frac{(2n)!}{n! \cdot (2n - n)!} - \frac{(2n)!}{(n - 1)! \cdot (2n - (n - 1))!} \\ &= \frac{(2n)!}{n! \cdot n!} - \frac{(2n)!}{(n - 1)! \cdot (n + 1)!} \\ &= \frac{(2n)!}{n! \cdot n!} - \frac{(2n)!}{n! \cdot n!} \cdot \frac{n}{n + 1} \\ &= \frac{\binom{2n}{n}}{n + 1} \end{align*} $$

公式4证明

$$ \begin{align*} \frac{\binom{2n}{n}}{n + 1} &= \frac{\binom{2n - 2}{n - 1} \cdot \frac{4n - 2}{n}}{n + 1} \\ &= \frac{\binom{2n - 2}{n - 1}}{n} \cdot \frac{4n - 2}{n + 1} \\ &= \frac{H_{n - 1} \cdot (4n - 2)}{n + 1} \end{align*} $$

例题

P1722 矩阵 II - 洛谷

矩阵 II
描述
众所周知,在中国古代算筹中,红为正,黑为负……

给定一个 $1\times 2n$ 的矩阵(usqwedf:这不是一个 $2n$ 的队列么),现让你自由地放入红色算筹和黑色算筹,使矩阵平衡[即 $\forall i \in[1, 2n]$,$1\sim i$ 格中红色算筹个数大于等于黑色算筹]。

问有多少种方案满足矩阵平衡(注意红色算筹和黑色算筹的数量必须相等)。

输入格式

正整数 $n$。

输出格式

方案数 $t$ 对 $100$ 取模后的结果。

样例输入

2

样例输出

2

数据范围:

$1\le n\le 100$

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef __int128 i128;
typedef long long ll;
typedef double db;

const db PI = acos(-1);
typedef array<ll, 2> PII; // vector<PII> a(n + 1);
const ll inf = 2e18 + 10;
// const int mod = 998244353;
const int maxn = 2e5 + 10;
bool multi = 0;

const int mod = 100;

void Solve() {
    ll n; cin >> n;
    vector<ll> cat(110);
    cat[0] = 1; cat[1] = 1;
    for(ll i = 2; i <= n; i ++ ) {
        for(ll j = 1; j <= i; j ++ ) {
            cat[i] += cat[j - 1] * cat[i - j];
            cat[i] %= 100;
        }
    }
    cout << cat[n] << '\n';
}


signed main() {
    // freopen("test.in","r",stdin);  
    // freopen("code.out","w",stdout);    
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    ll T = 1;
    if(multi) cin >> T;
    while(T -- ) {
        Solve();
    }
    return 0;
}