卡特兰数

原创 2018年04月17日 20:59:09

应用

 1.n个数进栈,有h(n)种出栈方式;
 2.凸n边形,用多条不相交的对角线分成三角形,有h(n-2)种可能性;
 3.n个节点,有h(n)种不同的二叉搜索树
 4.给n对括号排序,有h(n)种不同的正确的排序方式
 5.买票找零n个50元,m个100元(一开始柜台没零钱)
 6.n*n棋盘从左下角走到右上角而不穿过主对角线的走法
 7.矩阵连乘的括号化
 8.在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数
 9.9.n层阶梯矩阵切割成n个长度递增矩阵的切割法

公式

  • 递推关系: h(n)=h(n-1)*(4*n-2)/(n+1);
  • 通项公式①: h(n)=C(2n,n)/(n+1) (n=0,1,2,…)
  • 通项公式②:h(n)=C(2n,n)-C(2n,n-1)(n=0,1,2,…)
  • 扩展公式:h(n,m)=C(n+m,n)-C(n+m,n+1)

扩展公式应用于进出不同(左右括号数不同)时,(n代表必须先有的项数量,n>m,如左括号,入栈)

例题

原题 2018年长沙理工大学第十三届程序设计竞赛 J 杯子

题意

n个球顺序入栈出栈,求第m个球进栈时栈内有k个球的可能数

解析

分成两部分,

  1. 进m-1个,出m-k个 –> catalan(m-1,m-k)
  2. 已有k个,进n-m个,出n-m+k个 –> (n-m+k,n-m)

这道题对于当前任意一个元素之前的操作,一定是进栈大于等于出栈,对于当前元素后边的元素则一定是出栈大于等于进栈。
ans=C(n+m,n)-C(n+m,n+1)是计算卡特兰数的公式,可以理解为n个0,m个1,排列保证前i个1出现个数多于0(1<=i<=n+m)。根据上述条件进栈和出栈的代表的01意义交换了。

代码

//卡特兰数
/*   应用
     1.n个数进栈,有h(n)种出栈方式;
     2.凸n边形,用多条不相交的对角线分成三角形,有h(n-2)种可能性;
     3.n个节点,有h(n)种不同的二叉搜索树
     4.给n对括号排序,有h(n)种不同的正确的排序方式
     5.买票找零n个50元,m个100元(一开始柜台没零钱)
     6.n*n棋盘从左下角走到右上角而不穿过主对角线的走法
     7.矩阵连乘的括号化
     8.在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数
     9.n层阶梯矩阵切割成n个长度递增矩阵的切割法
*/
/*
递推关系:  h(n)=h(n-1)*(4*n-2)/(n+1);

通项公式:  h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
            h(n)=C(2n,n)-C(2n,n-1)(n=0,1,2,...)

进出不同(左右括号数不同)时:  h(n,m)=C(n+m,n)-C(n+m,n+1) 
(n代表必须先有的项数量,n>m,如左括号,入栈)
*/

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#include<ctime>
#include<cstdlib>
#include<sstream>
#include<functional>
#define D long long
#define F double
#define MAX 0x7fffffff
#define MIN -0x7fffffff
#define mmm(a,b) memset(a,b,sizeof(a))
#define for1(i,a,b) for(int i=a;i<=b;i++)
#define for2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
#define N 1001000
#define MOD (D)((int)1e9+7)
#define mod (D)((int)1e9+7)
const double pi=acos(-1);
const F eps=1e-6;
D read(){ D ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
//**************************************************************
//基础公式
D swift(D a,D b){
    D ans=1ll;
    while(b){
        if(b%2)ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }return ans;
}
D inv(D a){return swift(a,mod-2);}
D fac[N*3];
void init_fac(){
    fac[0]=fac[1]=1ll;
    for(int i=2;i<=2*N;i++)fac[i]=fac[i-1]*i%mod;
}
D C(D a,D b){//组合数
    if(b>a||b<0)return 0;
    return fac[a]*inv(fac[b])%mod*inv(fac[a-b])%mod;
}
//**************************************************************
//求和求法
D h[N];
void init(){
    h[0]=h[1]=1;
    for(int i=2;i<=N;i++){
        for(int j=0;j<i;j++){
            h[i]+=h[j]*h[i-j-1];
            h[i]%=mod;
        }
    }
}
//**************************************************************
//公式法
D catalan(D n){
    return (C(2*n,n)-C(2*n,n-1)+mod)%mod;
}
D catalan(D n,D m){//m为大者
    return (C(n+m,n)-C(n+m,n+1)+mod)%mod;
}
//**************************************************************

int main(){
    init_fac();
    int t=read();while(t--){
        D n=read(),m=read(),k=read();
        printf("%lld\n",catalan(m-1,m-k)*catalan(n-m+k,n-m)%mod);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许,不得转载~ https://blog.csdn.net/jk_chen_acmer/article/details/79980707

【算法】卡特兰数问题(BST排列个数,矩阵乘法,算数加括号,排队等)

卡特兰数当年大二时候就知道了其在行走路线问题上面的应用,后来发现其还有更多的应用场景,而且最近做LeetCode也碰见了不少这样的问题,特此总结一番。 本篇未完,待续 96. Unique Bi...
  • haolexiao
  • haolexiao
  • 2017-02-11 02:19:45
  • 869

卡特兰数相关问题总结

一、什么是Catalan数 说到Catalan数,就不得不提及Catalan序列,Catalan序列是一个整数序列,其通项公式是 递推公式是 C(n) = C(1)*C(n-1) + C(2...
  • JIEJINQUANIL
  • JIEJINQUANIL
  • 2016-08-08 17:11:21
  • 2046

卡特兰数公式推导

卡特兰数最常见的描述就是2n个球进站出站有多少种顺序推导:折线法,问题转化为从(0,0)到(2n,0)(0,0)到(2n,0) 每次可以向右上或者右下走一波,问在不越过x=0x=0 这条线的情况下,有...
  • lyc1635566ty
  • lyc1635566ty
  • 2017-06-26 21:58:36
  • 344

FZU 1064 教授的测试(卡特兰数,递归)

FZU 1064 教授的测试(卡特兰数,递归)
  • Dacc123
  • Dacc123
  • 2016-03-18 13:19:18
  • 724

关于卡特兰数的一些小理解

第k个卡特兰数记作CkCkC_k。 开始几项是 1,1,2,5,14,42….. 实际意义 有n对括号的合法括号序列匹配方案数 1..n顺次入栈,出栈序列方案数。 边数为n+2凸多边形三...
  • jokerwyt
  • jokerwyt
  • 2017-08-19 20:05:11
  • 592

卡特兰数的两种计算方法

卡特兰数的两种计算方法
  • cugbin
  • cugbin
  • 2015-11-25 20:23:45
  • 539

hdu-5668- Circle 逆元+卡特兰数知识模板

(a/b)%mod = (a%mod*(b的逆元))%mod 逆元求法: //1: 通用扩展欧几里得; long long extend_gcd(long long a,long long...
  • acblacktea
  • acblacktea
  • 2016-05-16 23:41:10
  • 347

卡特兰数——Catalan数(从一道腾讯笔试题引发的学习和思考)

卡特兰数——Catalan数(从一道腾讯笔试题引发的学习和思考)
  • u012333003
  • u012333003
  • 2014-04-16 09:14:48
  • 2331

组合数学之卡特兰数

卡特兰数: 1 通项公式:h(n)=C(n,2n)/(n+1)=(2n)!/((n!)*(n+1)!) 2递推公式:h(n)=((4*n-2)/(n+1))*h(n-1); h(n)=h(0)*h(...
  • u014097230
  • u014097230
  • 2015-03-13 19:00:18
  • 3474

前100个卡特兰数

留作备用 string catalan[]= { "1", "2", "5", "14", "42", "132", "429", "1...
  • qq_28954601
  • qq_28954601
  • 2016-09-28 20:38:52
  • 1075
收藏助手
不良信息举报
您举报文章:卡特兰数
举报原因:
原因补充:

(最多只允许输入30个字)