卡特兰数
来源:互联网 发布:javascript encodeuri 编辑:程序博客网 时间:2024/04/30 06:08
Codeblock的快捷键说明:
1、按住Ctrl滚滚轮,代码的字体会随你心意变大变小
2、
3、Ctrl+D可复制当前行或选中块
4、Ctrl+Shift+C注释掉当前行或选中块,Ctrl+Shift+X则解除注释。
5、Tab缩进当前行或选中块,Shift+Tab减少缩进
6、需要更大编辑空间时,F2和Shift+F2分别可以显隐下方Logs & others栏和左方的Management栏
7、Ctrl+PageUp 到达上一个函数,Ctrl+PageDown 到达下一个函数。 •Ctrl+B 添加书签
void *memset(void *s,int ch,size_t n);
函数解释:将 s 中前 n 个字节用 ch 替换并返回 s 。
头文件:#include
//卡特兰数:
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 ) = h(n-1)*(4*n-2) / (n+1)
卡特兰数:规定h(0)=1,而h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,h(6)=132,h(7)=429,h(8)=1430,h(9)=4862,h(10)=16796,h(11)=58786,h(12)=208012,h(13)=742900,h(14)=2674440,h(15)=9694845···
1,1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012,742900, 2674440, 9694845, 35357670, …
应用:
1、括号化
矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n-1)种)
f(n) = f(1)*f(n-1) + f(2)*f(n-2) + f(3)*f(n-3) +f(n-1)*f(1)
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0)(n>=2)
f(n) =h(n-1)
2、出栈次序
一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
分析:对于每一个数来说,必须进栈一次、出栈一次。我们把进栈设为状态‘1’,出栈设为状态‘0’。n个数的所有状态对应n个1和n个0组成的2n位二进制数。由于等待入栈的操作数按照1‥n的顺序排列、入栈的操作数b大于等于出栈的操作数a(a≤b),因此输出序列的总数目=由左而右扫描由n个1和n个0组成的2n位二进制数,1的累计数不小于0的累计数的方案种数。
设问题的解为f(2n),那么
f(2n) = f(0)*f(2n-2) + f(2)*f(2n-4) +f(2n-2)*f(0)
f(2n) = h(n)。
类似问题:
n对括号有多少种匹配方式?(h(n) )
3、凸多边形三角划分
在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。现在的任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)。比如当n=6时,f(6)=14
分析:因为凸多边形的任意一条边必定属于某一个三角形,所以我们以某一条边为基准,以这条边的两个顶点为起点P1和终点Pn(P即Point),将该凸多边形的顶点依序标记为P1、P2、……、Pn,再在该凸多边形中找任意一个不属于这两个点的顶点Pk(2<=k<=n-1),来构成一个三角形,用这个三角形把一个凸多边形划分成两个凸多边形,其中一个凸多边形,是由P1,P2,……,Pk构成的凸k边形(顶点数即是边数),另一个凸多边形,是由Pk,Pk+1,……,Pn构成的凸n-k+1边形。
此时,我们若把Pk视为确定一点,那么根据乘法原理,f(n)的问题就等价于——凸k多边形的划分方案数乘以凸n-k+1多边形的划分方案数,即选择Pk这个顶点的f(n)=f(k)×f(n-k+1)。而k可以选2到n-1,所以再根据加法原理,将k取不同值的划分方案相加,得到的总方案数为:
f(n)=f(2)f(n-2+1)+f(3)f(n-3+1)+……+f(n-1)f(2)。
f(n)=h(n-2)(n=2,3,4,……)。
最后,令f(2)=1,f(3)=1。
思路:以凸多边形的一边为基,设这条边的2个顶点为A和B。从剩余顶点中选1个,可以将凸多边形分成三个部分,中间是一个三角形,左右两边分别是两个凸多边形,然后求解左右两个凸多边形。
设问题的解f(n),其中n表示顶点数,设f(2) = 1,那么f(3) = 1, f(4) = 2, f(5) = 5。f(2)*f(n-1)表示三个相邻的顶点构成一个三角形,那么另外两个部分的顶点数分别为2和n-1。那么
f(n) = f(2)*f(n-1) + f(3)*f(n-2) +......f(n-2)*f(3) + f(n-1)*f(2)。
f(n) = h(n-2)。
类似问题:
在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
思路:以其中一个点为基点,编号为0,然后按顺时针方向将其他点依次编号。那么与编号为0相连点的编号一定是奇数,否则,这两个编号间含有奇数个点,势必会有个点被孤立,即在一条线段的两侧分别有一个孤立点,从而导致两线段相交。设选中的基点为A,与它连接的点为B,那么A和B将所有点分成两个部分,一部分位于A、B的左边,另一部分位于A、B的右边。然后分别对这两部分求解即可。
设问题的解f(n),那么
f(n) = f(0)*f(n-2) + f(2)*f(n-4) + f(4)*f(n-6) +......f(n-4)*f(2) + f(n-2)*f(0)。
f(0)*f(n-2)表示编号0的点与编号1的点相连,此时位于它们右边的点的个数为0,而位于它们左边的点为2n-2。依次类推。
f(0) = 1, f(2) = 1, f(4) = 2。结合递归式,不难发现
f(2n) =h(n)。
Cn = n*n 的方格地图中,从一个角到另外一个角,不跨越对角线的路径数;
4、给定节点组成二叉树
给定N个节点,能构成多少种不同的二叉树?(能构成h(N)个)(这个公式的下标是从h(0)=1开始的)
思路:可以这样考虑,根肯定会占用一个结点,那么剩余的n-1个结点可以有如下的分配方式,T(0, n-1),T(1, n-2),...T(n-1, 0),设T(i, j)表示根的左子树含i个结点,右子树含j个结点。
设问题的解为f(n),那么
假设f(0) = 1,那么f(1) = 1, f(2) = 2, f(3) =5。
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + .......+f(n-2)*f(1) + f(n-1)*f(0)。
f(n) = h(n).
实例:
1、描述:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?
f(2n) = h(n)*n!*n!。(后面的*n!*n!为进出栈的排列)
2、拥有n+1个叶子节点的二叉树的数量为h(n)
编程实例:
// 使用公式计算:h(n ) = h(n-1)*(4*n-2) / (n+1)
#include
#include
using namespace std;
//h(n ) = h(n-1)*(4*n-2) / (n+1)
int catelan1(int n)
{
}
//h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0)(n>=2)
int catelan2(int n)
{
}
//h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
int Cn(int n)
{
}
int catelan3(int n)
{
}
int main()
{
}
运行结果:
h(0):1
h(1):1
h(2):2
h(3):5
h(4):14
h(5):42
h(6):132
h(7):429
h(8):1430
h(9):4862
h(10):16796
Process returned 0(0x0)
Press any key to continue.
公式3有点问题。。。
还有一种分级排列法,没怎么看明白。。。
- 卡特兰数,高精度卡特兰数
- 卡特兰数
- 卡特兰数(Catalan)
- 卡特兰数
- 卡特兰数
- 卡特兰数 大数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 卡特兰数
- 计算机图形学(OPENGL 的 NOTE)
- OPENGL (DDA、Hermite、Bezie…
- OPENGL (动画,光照,纹理)
- 百度之星技术社区三月赛题
- 微软2012年实习生录取笔试题(及答…
- 卡特兰数
- 运行JavaScript
- JavaScript 的学习程序整理(…
- HTML整理程序
- cURL(学习、安装、应用)
- Win7下JAVA(JDK)的安装、环境配…
- HDU2063:Investment(完全背包)
- 江湖吟
- hadoop版本一中的线程唤醒问题