当前位置: 首页 > news >正文

卡特兰数问题

1. 前置知识-求组合数

求组合数 C a b = C a − 1 b − 1 + C b − 1 b C^b_a = C^{b-1}_{a-1}+C^{b}_{b-1} Cab=Ca1b1+Cb1b

C a b C^b_a Cab 的含义就是从 a a a 个数当中选 b b b 个数

  1. 如果我们不选第 a a a 个数: C a − 1 b C_{a-1}^b Ca1b
  2. 如果我们选第 a a a 个数: C a − 1 b C_{a-1}^{b} Ca1b

可以发现,就是一个动态规划的过程

  1. 边界条件为 C n 0 = 1 C_{n}^0=1 Cn0=1
  2. f [ a ] [ b ] f[a][b] f[a][b] C a b C_a^b Cab
  3. 时间复杂度 O ( N 2 ) O(N^2) O(N2)
int f[N][N];	
void dp()	
{
    f[0][0] = 1;
	for(int i = 1; i < N; i ++ )
	{
		for(int j = 0; j < N; j ++ )	
		{
			if(!j)	f[i][j] = 1;
			else f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) % mod;
		}
	}
}

2. 卡特兰数-例题引入

n n n n n n<= 13 13 13) 个字母 a b c abc abc…,依次进栈/出栈,有多少种可能的出栈序列
输入:一个正整数 3 3 3
输出:第一行为总方案数
例如:

3
--------
5
abc
acb
bac
bca
cba

代码一:输出路径,时间复杂度: O ( 2 2 n ) O(2^{2n}) O(22n)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>

using namespace std;

vector<int> path;
stack<int> s;
int res;

void dfs(int u, int n, int cnt)
{
    if(cnt == n)
    {
        res ++ ;
        for(int i = 0; i < n; i ++ )    cout << char(path[i] + 'a');
        cout << endl;
        return ;
    }
    if(s.size())    // 可以pop
    {
        auto t = s.top();   s.pop();
        path.push_back(t);
        dfs(u, n, cnt + 1);  // 由于当前元素没有使用,下一次仍然是从u开始
        path.pop_back();
        s.push(t);
    }
    if(u < n)   // 可以push
    {
        s.push(u);
        dfs(u + 1, n, cnt);
        s.pop();    // 别忘了这里也需要回溯
    }
}

int main()
{
    int n;  cin >> n;
    dfs(0, n, 0);  
    cout << res << endl;
    return 0;
}
// n=5:42
// n=3:5

代码二:只输出答案,数据很大,注意爆 i n t int int

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 50;

long long f[N][N]; // f[i][j] -> c_i^j

int main()
{
    int n;  cin >> n;
    for(int i = 0; i < N; i ++ )    f[i][0] = 1;
    for(int i = 1; i <= n << 1; i ++ )
        for(int j = 1; j <= n; j ++ )
            f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
    cout << f[n << 1][n] / (n + 1) << endl;
    return 0;
}

3. 卡特兰数

注意卡特兰数并不是只有一个形式( 1 1 + n C 2 n n \frac{1}{1+n}C_{2n}^{n} 1+n1C2nn
ref1

ref2

ref3

4. 补充习题

不同的搜索二叉树的个数
n个节点最多可组成多少不同形态的二叉树
火车进出站问题

相关文章:

  • 端侧设备(如路由器、家庭网关、边缘计算盒子、工业网关等)的典型系统、硬件配置和内存大小
  • 【矩阵快速幂】P2100 凌乱的地下室|省选-
  • AI+基础工具:解锁业务增长原子级能力,To B 落地新方向
  • 红宝书第十九讲:详解JavaScript的Fetch API与Ajax请求
  • 利用虚拟化技术实现高级Hook
  • Success is the sum of small efforts repeated day in and day out.
  • 1.Python 计算机二级题库:选择题
  • 【大模型】视觉语言模型:Qwen2.5-VL的使用
  • 分布式ID生成器:雪花算法原理与应用解析
  • 航拍数据集汇总,覆盖车辆/船舶检测/物体评估/城市景观……
  • 了解图像质量评价指标PSNR
  • JAVA实现动态IP黑名单过滤
  • 基于聚类与引力斥力优化的选址算法
  • 71. 我的第一个Linux驱动实验
  • 树莓派超全系列文档--(11)RaspberryOS上使用 Python控制GPIO
  • 鸿蒙项目源码-购物商城v2.0-原创!原创!原创!
  • 【Java】JVM
  • 优化MyBatis-Plus批量插入策略
  • 第十二章:补充介绍pip与配置及Python结构层次
  • Django数据库迁移报错解决方案
  • 新买的服务器怎么做网站/seo基础培训机构
  • 新站整站优化/seo资源网站 排名
  • 风景网站模板/哪个搜索引擎最好用
  • 青岛做网站大公司有哪些/互联网广告销售好做吗
  • 国外做鞋子的网站/指数分布的期望和方差
  • 苏州相城做网站哪家好/营销方案ppt