卡特兰数
来源:互联网 发布:淘宝哪家二手单反店好 编辑:程序博客网 时间:2024/04/28 23:18
How Many Trees?
题意:给定一棵n个节点的二叉树, 求这棵树有多少个二叉树。
数据范围: n<=100
思路:
n个节点的二叉树有多种,多种二叉树里面又有子树。当n到达100时,结果是一个庞大的数字,所以要用到大数。
在卡特兰数的应用里面,求二叉树的个数是一个典型的应用,还有 合法的入栈出栈序列数、多边形分成三角形的个数、圆括弧插入公式中的方法数 都是卡特兰数的应用
卡特兰数详解: Math173 (这个版面好看)
代码:
#include <stdio.h> //最大到100,进行预处理#include <iostream>#include <string.h>#define base 10000#define maxn 100 using namespace std;int num[105][100];void multiply(int a[],int b){int i,temp = 0;for(i = maxn - 1; i >= 0; i--){temp += a[i]*b;a[i] = temp%base;temp /= base;}}void dive(int a[],int b){int i,temp = 0;for(i = 0; i < maxn; i++){temp = temp*base + a[i];a[i] = temp / b;temp %= b;}}int main(){int i,n;memset(num,0,sizeof(num));num[1][maxn-1] = 1;for(i = 2; i <= 100;i++){memcpy(num[i],num[i-1],maxn*sizeof(int));multiply(num[i],4*i-2);dive(num[i],i+1);}while(scanf("%d",&n)!=EOF){i = 0;while(num[n][i] == 0)i++;printf("%d",num[n][i++]);for(; i < maxn; i++){printf("%04d",num[n][i]);}printf("\n");}return 0;}
以上等价于求 n个入栈操作,n个出栈操作,典型的入栈操作数 等于 出栈操作数,但是还有不等于的情况,如下:
Buy the Ticket
题意:电影院卖票。一张票50元。一开始没有零钱。有m+n个人买票,m个人拿50元的钞票,n个人拿100的。问队伍有多少种排列方式可以使得卖票能顺利进行下去。
数据范围:m, n <=100 , m==n==0结束输入
题解:很典型的卡特兰数,详情参见 i_fuqiang的专栏
代码:
#include <iostream>#include <string>using namespace std;#define MAX 100#define BASE 10000void 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 fact[205][MAX];void setFact () //求出0-200的阶乘值 { fact[0][MAX-1] = fact[1][MAX-1] = 1; for ( int i = 2; i <= 200; ++ i ) { memcpy ( fact[i] , fact[i-1] , MAX * sizeof ( int ) ); multiply ( fact[i] , MAX , i ); } }void outPut ( int ctl[MAX] ){ int i = 0; while ( i < MAX && ctl[i] == 0 )//去掉前面的为0的项 { i ++ ; } printf ( "%d", ctl[i++] ); while ( i < MAX ) { printf ( "%04d", ctl[i++] ); } putchar ( '\n' ); }int res[MAX];int main (){ int M,N; int ca = 1; setFact(); //打表 while ( cin >> M >> N , M + N ) { printf ( "Test #%d:\n",ca++ ); if ( N > M ) { puts ( "0" ); continue; } memcpy ( res , fact[M+N] , MAX * sizeof ( int ) ); //阶乘 ( m + n )! multiply ( res, MAX, M - N + 1 ); // ( m + n )! * ( m-n+1 ) divide ( res, MAX, M + 1 ); // ( m + n )! * ( m-n+1 ) / ( m+ 1 ) outPut ( res ); } return 0;}
阅读全文
0 0
- 卡特兰数,高精度卡特兰数
- 卡特兰数
- 卡特兰数(Catalan)
- 卡特兰数
- 卡特兰数
- 卡特兰数 大数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 文章标题
- [偏难] UVa OJ 1572 有向图判环
- 信息系统项目管理师EV、PV、AC、BAC、CV、SV、EAC、ETC、CPI、SPI概念说明
- linux下编辑profile文件
- 欢迎使用CSDN-markdown编辑器
- 卡特兰数
- 前奇后偶
- MySql数据库查询——使用聚合函数查询
- 2017.8.29 miniblink更新日记
- Hive
- QT中用opencv遍历一个图片(一种思路,不是最佳,有空再补充)
- POJ2828 Buy Tickets(树形DP)
- 1042. 字符统计(20)
- 去掉系统自带导航栏下边的线条(备忘)