Catalan

卡特兰数前几项为 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900,2674440, 9694845,35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ... 令h(0)=1,h(1)=1,

catalan数满足递推式[1]:

h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2) 例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2 h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5

递推关系的另类解为: h(n)=c(2n,n)-c(2n,n+1)(n=0,1,2,...)

卡特兰数的递推公式为:h(n)=h(n-1)*(4*n-2)/(n+1);

应用问题 实质上都是递推等式的应用 : 1:矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序, 只用括号表示成对的乘积, 试问有几种括号化的方案?(h(n-1)种)[3]出栈次序

2: 一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?[4-5]

3: 类似问题 买票找零 有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票, 剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零? (将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)

4:

凸多边形三角划分 在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。 现在的任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)。比如当n=6时,f(6)=14。[6] 分析

因为凸多边形的任意一条边必定属于某一个三角形,所以我们以某一条边为基准, 以这条边的两个顶点为起点P1和终点Pn(P即Point),将该凸多边形的顶点依序标记为P1、P2、……、Pn, 再在该凸多边形中找任意一个不属于这两个点的顶点Pk(2<=k<=n-1),来构成一个三角形, 用这个三角形把一个凸多边形划分成两个凸多边形,其中一个凸多边形,是由P1,P2,……, Pk构成的凸k边形(顶点数即是边数),另一个凸多边形,是由Pk,Pk+1,……,Pn构成的凸n-k+1边形。 此时,我们若把Pk视为确定一点,那么根据乘法原理,f(n)的问题就等价于——凸k多边形的划分方案数乘 以凸n-k+1多边形的划分方案数,即选择Pk这个顶点的f(n)=f(k)×f(n-k+1)。 而k可以选2到n-1,所以再根据加法原理,将k取不同值的划分方案相加,得到的总方案数为: f(n)=f(2)f(n-2+1)+f(3)f(n-3+1)+……+f(n-1)f(2)。看到此处,再看看卡特兰数的递推式, 答案不言而喻,即为f(n)=h(n-2) (n=2,3,4,……)。 最后,令f(2)=1,f(3)=1。 此处f(2)=1和f(3)=1的具体缘由须参考详尽的“卡特兰数”, 也许可从凸四边形f(4)=f(2)f(3)+ f(3)f(2)=2×f(2)f(3)倒推, 四边形的划分方案不用规律推导都可以知道是2,那么2×f(2)f(3)=2,则f(2)f(3)=1, 又f(2)和f(3)若存在的话一定是整数,则f(2)=1,f(3)=1。

5:

类似问题 编辑本段 一位大城市的律师在她住所以北n个街区和以东n个街区处工作。 每天她走2n个街区去上班。如果她从不穿越(但可以碰到)从家到办公室的对角线, 那么有多少条可能的道路? 在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?

下面总结了卡特兰数的一个模板 这里用的是 卡特兰数的递推公式为:h(n)=h(n-1)*(4*n-2)/(n+1); 也就是一个高精度问题的求解

hdu:1134

#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;

int a[105][105];    //大数卡特兰数
int b[105];         //卡特兰数的长度
void catalan()  //求卡特兰数

{
    int i, j, len, carry, temp;
    a[1][0] = b[1] = 1;
    len = 1;
    for(i = 2; i <= 100; i++)

{
        for(j = 0; j < len; j++)    //乘法
            a[i][j] = a[i-1][j]*(4*(i-1)+2);
        carry = 0;
        for(j = 0; j < len; j++)    //处理相乘结果

{
            temp = a[i][j] + carry;
            a[i][j] = temp % 10;
            carry = temp / 10;
       }

while(carry)    //进位处理
        {
            a[i][len++] = carry % 10;//这里这样写是为了记住b[i]所对应的len
            carry /= 10;
        }
        carry = 0;
        for(j = len-1; j >= 0; j--) //除法,这里看的不是很懂。比如28/6的话就等于4了
        {
            temp = carry*10 + a[i][j];
            a[i][j] = temp/(i+1);
            carry = temp%(i+1);
        }

while(!a[i][len-1])     //高位零处理
            len --;
        b[i] = len;
    }
}

int main()
{
    int i, n;
    catalan();
    while(scanf("%d", &n) != EOF)
    {

for(i = b[n]-1; i>=0; i--)//这样话,对于打表求解的话确实很省时间
        {
            printf("%d", a[n][i]);
        }

printf("\n");

}

return 0;

}

时间: 2024-10-10 07:55:36

Catalan的相关文章

Catalan数

[问题描述]对于一个栈,已知元素的进栈序列,判断一个由栈中所有元素组成的排列的出栈序列. 有N个数,则代表入栈序列为1,2,3,4,5...,N.求所有可能的出栈序列和总数. 代码如下 #include<iostream> #include<vector> #include<algorithm> #include<string> #include<stdio.h> using namespace std; int N = -1; int sum

【noi 2.6_9288】&amp;【hdu 1133】Buy the Ticket(DP / 排列组合 Catalan+高精度)

题意:有m个人有一张50元的纸币,n个人有一张100元的纸币.他们要在一个原始存金为0元的售票处买一张50元的票,问一共有几种方案数. 解法:(学习了他人的推导后~) 1.Catalan数的应用7的变形.(推荐阅读:http://www.cnblogs.com/chenhuan001/p/5157133.html).P.S.不知我之前自己推出的公式“C(n,m)*C(2*m,m)/(m+1)*P(n,n)*P(m,m)”是否是正确的. (1)在不考虑m人和n人本身组内的排列时,总方案数为C(m+

UVA 10312 - Expression Bracketing(数论+Catalan数)

题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1253">10312 - Expression Bracketing 题意:有n个x,要求分括号,推断非二叉表达式的个数. 思路:二叉表达式的计算方法就等于是Catalan数的,那么仅仅要计算出总数,用总数减去二叉表达式个数.得到的就是非二叉表达式的个数. 那么计算方法是什么呢. 看题目中的图,对于n = 4的情况,能够分为这几种情况来讨论

hdu 5370 Tree Maker(catalan+dp)

题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言,被移动过的节点就是确定的位置,所以只要知道已经确定位置的K个节点有多少个空孩子指针M,和就该子树下的N个未确定位置的节点,等于是说用N个节点构造M个可为空的子树的种类数.对于整个树的形态数即为若干棵独立的子树形态数的乘积. 定义dp[i][j]为用i个节点构造j棵树的形态数,dp[i][j] = sum{ dp[i-1][j-k] * catalan[k] | 0 ≤ k ≤j }

UVA10303 - How Many Trees?(java大数+catalan数)

UVA10303 - How Many Trees?(java大数+catalan数) 题目链接 题目大意:给你1-N N个数,然后要求由这些数构成二叉搜索树,问有多少种这样的二叉搜索树. 解题思路:把前5项理出来,正好是1 2 5 14 42..就猜想是catalan数,结果也是对了.公式f(i + 1) = (4?i - 6)/ i; (i >= 2).结果很大,要用高精度. 代码: import java.util.*; import java.math.*; import java.io

卡特兰数(Catalan)

卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列.由以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名,其前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796. 通项:f(n) = f(0)*f(n-1) + f(1)*f(n-2) + .......+ f(n-2)*f(1) + f(n-1)*f(0) n>=2 f(n)=f(n-1)*(4n-2)/(n+1) 应用场景:

【64测试20161112】【Catalan数】【数论】【扩展欧几里得】【逆】

Problem: n个人(偶数)排队,排两行,每一行的身高依次递增,且第二行的人的身高大于对应的第一行的人,问有多少种方案.mod 1e9+9 Solution: 这道题由1,2,5,14 应该想到Catalan数,但是我却花了两个小时去找递推式. 首先 Catalan数 : 基本规律:1,2,5,14,42,132,.......... 典型例题: 1.多边形分割.一个多边形分为若干个三角形有多少种分法. C(n)=∑(i=2...n-1)C(i)*C(n-i+1) 2.排队问题:转化为n个人

【catalan数】10076 - 凸多边形分割

[catalan数]10076 - 凸多边形分割 Time Limit: 1000MS Memory Limit: 32768KB 这题不能用通项公式 我忘记了mod不支持除法 我忘记了mod不支持除法 1 # include<cstdio> 2 # include<iostream> 3 using namespace std; 4 const int maxn=250; 5 typedef unsigned long long LL; 6 LL f[maxn]; 7 int m

[LeetCode系列]卡特兰数(Catalan Number) 在求解独特二叉搜寻树(Unique Binary Search Tree)中的应用分析

本文原题: LeetCode. 给定 n, 求解独特二叉搜寻树 (binary search trees) 的个数. 什么是二叉搜寻树? 二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉排序树. 举个栗子,给定 n = 3, 共有 5 个. 1 3 3 2 1 \ / / / \ 3 2 1 1

uva 10312 - Expression Bracketing(Catalan+SuperCatalan)

Set集合的配置 数据表的创建:表关系一个员工拥有多个身份 create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR(20) default NULL, last_name VARCHAR(20) default NULL, salary INT default NULL, PRIMARY KEY (id) ); create table CERTIFICATE ( id INT NOT NULL aut