【算法专题】卡特兰数(计数数列)

Catalan数列:1 1 1 2 5 14 42 132 429 1430 4862 16796

【计数映射思想】

参考:卡特兰数 — 计数的映射方法的伟大胜利

计数映射:将难以统计的数映射为另一种形式的可以统计的数。

一、入栈出栈序

n个数字,有多少种合法的入栈出栈序列?n=3时的合法序列之一:+1,-1,+1,+1,-1,-1

对于n个数字,就是要在2n个1中添加n个“+”,则序列总数C(2n,n)。

对于未入栈先出栈的不合法情况,在其第一次前缀和为-1时,将前面的所有符号反转,此时整个序列有n+1个“+‘和n-1个’-‘,每个不合法序列都映射为2n个1中添加n+1个‘+‘构成的序列。

正向:每个不合法序列第一个前缀和为-1的位置反转后,形成的序列不同。

反向:每个含n+1个"+"的序列,第一个前缀和为1的位置反转后,形成的不合法序列不同。

所以得到卡特兰数:Cn=C(2n,n)-C(2n,n-1)=C(2n,n)/(n+1)

例一、含n+1个节点的满二叉树形态数:中序遍历,向左+1向右-1,转化为入栈出栈序。

例二、圆上n个点连弦数:顺时针顺序每次+1和-1连弦,转化为入栈出栈序。

例三、n对括号表达式:左括号+1右括号-1,括号表达式组合数转化为入栈出栈序。

例四、n+1个数字连乘:结合n次即有n对有效括号,转化为括号表达式。

例五、凸n+2边形的三角剖分数:对边进行编号,然后顺时针扫描,实际上是n+1条边的连乘方案,转化为入栈出栈序。

二、不跨线路径数(几何模型)

入栈出栈序:考虑n*n的方格,从左下到右上不跨越对角线的路径数,向右记为+1,向上记为-1,跨越对角线就是前缀和为-1,则转化为入栈出栈序。

考虑n*m的方格,一条不合法路径在第一次跨越对角线的时候,将前面的路径翻转(上变左,左变上),那么就变成了到(n-1,m+1)的路径数。

那么f(n,m)=C(n+m,n)-C(n+m,n-1)。

【分治思想】

一个问题A,规模为n,可以用分治的思想,先固定一个元素,然后将剩下n-1个元素拆分成两个问题,根据固定的元素位置不同,两个问题分别是(0,n-1)(1,n-2)...(n-1,0)。

例一、入栈出栈序:固定最后出栈的数字是第k个加入的数,那么k前面是k-1个数的入栈出栈序问题,k后面是n-k个数的入栈出栈序问题,则有:

C(n)=C(0)*C(n-1)+C(1)*C(n-2)+...+C(n-1)C(0),即C(n)=ΣC(i)*C(n-i-1),i=0~n-1,C(0)=1

例二、凸n+2边形三角剖分数:先固定三角形V1VkVn+2,划分成凸k多边形和凸n+2-k边形,转化为Cn。

★总结:Catalan数的题目,一般从几种方式看出:转化为入栈出栈序,转化为几何不跨线路径数,定点分治思想,打表

原文地址:https://www.cnblogs.com/onioncyc/p/8213374.html

时间: 2024-10-10 23:37:37

【算法专题】卡特兰数(计数数列)的相关文章

卡特兰数(Catalan Number) 算法、数论 组合~

Catalan number,卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列.以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名. 卡特兰数的前几个数 前20项为(OEIS中的数列A000108):1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190

【卡特兰数】BZOJ1485: [HNOI2009]有趣的数列

Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<…<a2n-1,所有的偶数项满足a2<a4<…<a2n: (3)任意相邻的两项a2i-1与a2i(1≤i≤n)满足奇数项小于偶数项,即:a2i-1<a2i. 现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列.因为最后的答案可能很大,所以只要求输出答案 mod P的

bzoj1485 [HNOI2009]有趣的数列 卡特兰数

[bzoj1485][HNOI2009]有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<…<a2n-1,所有的偶数项满足a2<a4<…<a2n: (3)任意相邻的两项a2i-1与a2i(1≤i≤n)满足奇数项小于偶数项,即:a2i-1<a2i. 现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列.因为

[HNOI2009]有趣的数列 题解(卡特兰数)

[HNOI2009]有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<...<a2n-1,所有的偶数项满足a2<a4<...<a2n: (3)任意相邻的两项a2i-1与a2i(1<=i<=n)满足奇数项小于偶数项,即:a2i-1<a2i. 现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列.

有趣的数列 唯一分解定理+卡特兰数

问题: 我们称一个长度为\(2n\)的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从\(1\)到\(2n\)共\(2n\)个整数的一个排列{\(Ai\)}: (2)所有的奇数项满足\(A1<A3<-<A2n-1\),所有的偶数项满足\(A2<A4<-<A2n\): (3)任意相邻的两项\(A2i-1\)与\(A2i(1≤i≤n)\)满足奇数项小于偶数项,即:\(A2i-1<A2i\). 现在的任务是:对于给定的\(n\),请求出有多少个不同的长度为\

卡特兰数高精度算法

很多组合题都会用到卡特兰数,增长速度又很快,应该写个高精度尊敬一下~ 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define ML 549 5 using namespace std; 6 int kt[105][550]; 7 int len[105]; 8 int getlen(int ord) 9 { 10 int pos; 11 for(int i=ML;i>=0;i

括号序列计数 数形结合 卡特兰数

问长度为 2n 的括号序列有多少个. 以 ( 的数量为 x 轴, ) 的数量为 y 轴, 建立坐标系. 初始状态对应 (0, 0) . 假设当前在 (x, y) , 如果下一位为 ( , 那么转移到 (x, y) + (1, 0) , 否则转移到 (x, y) + (0, 1) . 现在要求不超过 y = x 的从 (0, 0) 到 (n, n) 的路径数. 我们考虑用从 (0, 0) 到 (n, n) 的总的路径数, 减去非法的路径数. 总的路径数为 $\binom{2n}{n}$ . 对于非

【数论】卡特兰数

Catanlan Number     卡特兰数,又称卡塔兰数(Catanlan Number),是一个非常多见.高深的数列.它能解决我们数论题目中一些计数问题.前几项为:1,2,5,14,42,132,429,1430,4862,16796,58786……          那么如何求Catanlan Number的第N项呢? 1. 2. 3. 4. 5. 着重需要介绍一下的是卡特兰数的功能 例一:二叉树的计数 n个非叶节点的满二叉树的形态数(对称后得到的二叉树除非自己本身对称,否则算是不同)

hdu4165(简单递推,实则卡特兰数的应用)

这道题之前自己做的时候并没有反应过来是求卡特兰数,当时是按递推来想的.后来查了下HDU4165,结果一看大标题就说是卡特兰数,自己想了想,还真是那么回事.主要还是对于卡特兰数用的不多,也就当时没立马反应过来了.下面介绍这道题我的思路,然后对卡特兰数再做一些补充. 本题题意:罐子里有N片相同的药片,开始的时候药片都是完整的一整片.然后一个每天从中任意取一片,如果该药片是完整的一整片,那么他会吃点半片,然后将剩余半片扔回罐里,如果恰好是半片,那他直接吃掉拿出来的半片.显然2N天后,他吃完全部N片药片