卡特兰数及其应用总结

寵の児 提交于 2020-02-16 21:27:13

优秀blog
优秀blog

卡特兰数


定义

卡特兰数是组合数学中一个常出现在各种计数问题中的数列。

给定n个0,n个1,排成2n的序列,满足:任意前缀中0的个数大于等于1的个数的排列方式种数,即为卡特兰数。

其前几项为(从第零项开始) : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796


递推公式

设h(n)为catalan数的第n+1项,令h(0)=1,h(1)=1

  1. h(n)= h(0) * h(n-1)+h(1) *h(n-2) + … + h(n-1) *h(0) (n>=2)

    eg : h(3)=h(0) *h(2)+h(1) *h(1)+h(2) *h(0)=1 *2+1 *1+2 *1=5

  2. 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,…)


求卡特兰数—代码

用组合数算

组合数的计算

for(int i=0; i<=4000; i++) 
        c[i][0] = c[i][i] = 1;
for(int i=2;i<=n;i++)
        for(int j=1;j<=i/2;j++) {
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
            c[i][i-j]=c[i][j];
        }

公式:h(n) = c(2n,n) - h(2n,n-1)
注意: int c[maxn][maxn]; 要写到main外面

for(int i=0; i<=4000; i++)
        c[i][0] = c[i][i] = 1;
    for(int i=2 ; i<=4000; i++)
        for(int j=1; j<=i/2; j++){
            c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
            c[i][i-j] = c[i][j];
        }
    cin >> n;
    cout << (c[2*n][n] - c[2*n][n-1] + mod) % mod << endl;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=2100;
ll dp[maxn];
ll mypow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

int main(void)
{
    int n;
    scanf("%d",&n);
    dp[1]=1;
    for(int i=2;i<=n;i++)
        dp[i]=dp[i-1]*(4*i-2) % mod * mypow(i+1,mod-2) % mod;
    printf("%lld\n",dp[n]);
    return 0;

}


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!