前几个卡特兰数:规定C0=1,而
C1=1, C2=2, C3=5,
C4=14, C5=42,
C6=132, C7=429, C8=1430,
C9=4862, C10=16796,
C11=58786,C12=208012,C13=742900,C14=2674440,C15=9694845。
求卡特兰数的公式有一下几个:
- h(n) = h(n-1)*(4*n-2)/(n+1)
- h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
- h(n)=C(2n,n)/(n+1)
(n=0,1,2,...) - h(n)=c(2n,n)-c(2n,n+1)(n=0,1,2,...)
下面给出一个卡特兰数的大数运算:能精确运算100以内的卡特兰数。
/* 大数解 对于大数来说,就应该使用下面的大数算法。 使用的公式为:h(n) = h(n-1)*(4*n-2)/(n+1); */ // 0ms #include<iostream> #include<cstring> #include<stdio.h> using namespace std; #define MAX 100 //能计算的最大值10000^100,最大为400位 #define BASE 10000 void multiply(int a[],int Max,int b) //大数乘法,注意参数的传递 { int i,array=0; for (i = Max-1; i >= 0; i--) { array += b * a[i]; a[i] = array % BASE; // 数组每一位存放大数的四位数字 array /= BASE; } } void divide(int a[], int Max, int b) //模拟大数除法 { int i, div = 0; for (i = 0; i < Max; i++) { div = div * BASE + a[i]; a[i] = div / b; div %= b; } } int main() { int a[101][MAX],i, n; memset(a[1],0,MAX*sizeof(int)); for (i=2, a[1][MAX-1] = 1; i < 101; i++) // 高坐标存放大数低位 { memcpy(a[i], a[i-1], MAX * sizeof(int)); //h[i] = h[i-1]; multiply(a[i], MAX, 4 * i - 2); //h[i] *= (4*i-2); divide(a[i], MAX, i + 1); //h[i] /= (i+1); } while (cin >> n) { for (i = 0; i < MAX && a[n][i] == 0; i++); //去掉数组前为0的数字。 cout << a[n][i++]; //输出第一个非0数 for (; i < MAX; i++) { printf("%04d",a[n][i]); //输出后面的数,并每位都保持4位长度!(32767) } cout << endl; } return 0; }
关于具体的运用别的博客上介绍的很清楚了。
下面只写出自己觉得有点意思的.........
12个人高低不同 站成两排,每一排的人必须是按照从低到高的顺序排,并且第一排对应的那个第二个人必须必第一排的人高。问一共有多少种方法。这个题目,我们可以这样来想:用0表示在第一排,用1表示在第二排。
比如000000111111表示的就是
1 2 3 4 5 6
7 8 9 10 11 12
000110001111 表示的就是
1 2 3 6 7 8
4 5 9 10 11 12
多少种排列方法就是满足所描述条件的排列有多少,很明显就是一个进栈出栈的问题了。
所以题目的答案就是卡特兰数(6)
时间: 2024-10-13 18:36:48