acwing算法基础之数学知识--求卡特兰数

目录

  • [1 基础知识](#1 基础知识)
  • [2 模板](#2 模板)
  • [3 工程化](#3 工程化)

1 基础知识

题目:给定n个0和n个1,它们将按照某种顺序排成长度为2n的序列,求它们能排成的所有序列中,能够满足任意前缀序列中0的个数都不少于1的个数的序列有多少个?

输出的答案对 1 0 9 + 7 10^9+7 109+7取模。

原题目等价于,

在平面直角坐标系xoy下,起点为(0,0),终点为(n,n),每次只能向上走一格或向右走一格,问从起点走到终点,且路径上横坐标大于等于纵坐标恒成立,求有多少种走法?

用下图表示即为,

在不触碰到红线(即 y = x + 1 y=x+1 y=x+1)的情况下,从起点(0,0)走到终点(n,n),有多少种走法。

考虑一种触碰到红线,走到终点(n,n)的路径,如下图粗蓝色所显示路径。我们将从首次触碰到红线的点,记作红点。那么,将接下来的路径按照红线( y = x + 1 y=x+1 y=x+1)对称,可以得到粗绿色所显示路径,最终走到点(n-1,n+1)。

也就是说,任何一条触碰红线,走到终点(n,n)的路径,都可以等效成,一条走到(n-1,n+1)的路径。而从起点走到点(n-1,n+1)的路径数为 C 2 n n − 1 C_{2n}^{n-1} C2nn−1,故触碰红线走到终点的路径数目为 C 2 n n − 1 C_{2n}^{n-1} C2nn−1。

题目要计算的是,不触碰红线走到终点(n,n)的路径数目,它等于总路径数目减去触碰红线走到终点(n,n)的路径数目,即答案可计算如下,
C 2 n n − C 2 n n − 1 = ( 2 n ) ! n ! ⋅ n ! − ( 2 n ) ! ( n − 1 ) ! ⋅ ( n + 1 ) ! C_{2n}^n-C_{2n}^{n-1}=\frac{(2n)!}{n!\cdot n!} - \frac{(2n)!}{(n-1)!\cdot (n+1)!} C2nn−C2nn−1=n!⋅n!(2n)!−(n−1)!⋅(n+1)!(2n)!
= ( 2 n ) ! ( n − 1 ) ! ⋅ n ! ⋅ ( 1 n − 1 n + 1 ) = ( 2 n ) ! ( n − 1 ) ! ⋅ n ! ⋅ 1 n ( n + 1 ) =\frac{(2n)!}{(n-1)!\cdot n!}\cdot (\frac{1}{n} - \frac{1}{n+1})=\frac{(2n)!}{(n-1)!\cdot n!}\cdot \frac{1}{n(n+1)} =(n−1)!⋅n!(2n)!⋅(n1−n+11)=(n−1)!⋅n!(2n)!⋅n(n+1)1
= ( 2 n ) ! n ! ⋅ n ! ⋅ 1 n + 1 = C 2 n n n + 1 =\frac{(2n)!}{n!\cdot n!} \cdot \frac{1}{n+1}=\frac{C_{2n}^n}{n+1} =n!⋅n!(2n)!⋅n+11=n+1C2nn

其中 C 2 n n n + 1 \frac{C_{2n}^{n}}{n+1} n+1C2nn即为卡特兰数。

转换为代码,如下,

cpp 复制代码
#include <iostream>

using namespace std;

const int mod = 1e9 + 7;

int qmi(int a, int k, int p) {
    int res = 1;
    while (k) {
        if (k & 1) res = (long long)res * a % p;
        k >>= 1;
        a = (long long)a * a % p;
    }
    return res;
}

int main() {
    int n;
    cin >> n;
    
    //计算C[2 * n][n] / (n + 1) % mod
    int res = 1;
    for (int i = 1, j = 2 * n; i <= n; ++i, --j) {
        res = (long long)res * j % mod;
        res = (long long)res * qmi(i, mod - 2, mod) % mod;
    } 
    res = (long long)res * qmi(n + 1, mod - 2, mod) % mod;
    cout << res << endl;
    return 0;
}

2 模板

暂无。。。

3 工程化

暂无。。。

相关推荐
凌肖战4 分钟前
力扣上刷题之C语言实现(数组)
c语言·算法·leetcode
编程版小新5 分钟前
C++初阶:STL详解(四)——vector迭代器失效问题
开发语言·c++·迭代器·vector·迭代器失效
秋夫人31 分钟前
B+树(B+TREE)索引
数据结构·算法
梦想科研社1 小时前
【无人机设计与控制】四旋翼无人机俯仰姿态保持模糊PID控制(带说明报告)
开发语言·算法·数学建模·matlab·无人机
Milo_K1 小时前
今日 leetCode 15.三数之和
算法·leetcode
Darling_001 小时前
LeetCode_sql_day28(1767.寻找没有被执行的任务对)
sql·算法·leetcode
AlexMercer10121 小时前
【C++】二、数据类型 (同C)
c语言·开发语言·数据结构·c++·笔记·算法
Greyplayground1 小时前
【算法基础实验】图论-BellmanFord最短路径
算法·图论·最短路径
蓑 羽1 小时前
力扣438 找到字符串中所有字母异位词 Java版本
java·算法·leetcode
源代码:趴菜1 小时前
LeetCode63:不同路径II
算法·leetcode·职场和发展