卡特兰数
定义
卡特兰数是组合数学中一个常出现在各种计数问题中的数列。
给定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
-
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
-
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;
}
来源:CSDN
作者:jhckii
链接:https://blog.csdn.net/jhckii/article/details/104340628