偶然看到的题目,居然可以用卡特兰数解。
12个人排两排,每排都按身高由小到大排,要求第二排相应位置上每个人的身高都比第一排上的人要高,问有多少种排法?
卡特兰数的一个模型就是括号匹配。先给括号标号(序号对应身高),我们把左括号当作第一排的人,右括号当作第二排的人。
| 1 | 2 | 3 | 4 | 5 | 6 |
| ( | ( | ) | ( | ) | ) |
第一排 | 1 | 2 |
| 4 |
|
|
第二排 |
|
| 3 |
| 5 | 6 |
有结论:
- 左/右括号的序号递增(满足两排都有序)
- 第n个右括号之前必定至少有n左括号(排在第二排某个位置,对应第一排的肯定比其小)
我们可以得出括号匹配可以对应到身高排列。还要证反过来也成立。
先明确这里身高对应排列序号,合法的括号匹配就是左右括号数量一致(这里显然),并且前面的“第n个右括号之前必定至少有n左括号”。
对于每一个满足要求的身高排列,
a1 | < | a2 | < | a3 |
ʌ |
| ʌ |
| ʌ |
b1 | < | <>b2 | < | b3 |
对b1,我们知道身高小于b1的a至少有a1
对于b2,我们知道身高小于b2的a至少有a1,a2
。。。。
我们让a对应(,b对应),而括号的位置序号对应身高序号。
所以可以证明按身高排序的ai 和bi序列,替换成括号后是合法匹配。
小结一下Catalan数
令h( 0 ) = 1 ,h( 1 )= 1 ,catalan数满足递归式:
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 = 1 , 2 , 3 , ...)
得到式子:
- 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 ) = C(2n,n)-C(2n, n+1) (n = 1 , 2 , 3 ,...)
式子1对应的模型:
- 在圆上选择2n个点,将这些点成对连接起来,使得所得到的n条线段不相交的方法数。
- 将一个凸n+2边形区域分成三角形区域的方法数 。
- 给定N个节点,能构成多少种形状不同的二叉树?(一定是二叉树 ! 先取一个点作为顶点,然后左边依次可以取0至N - 1个相对应的,右边是N - 1到0个,两两配对相乘 )
- 矩阵链乘: P = a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的 乘积,试问有几种括号化的方案?切割成左右两块(a1 x a2 ... x ak)( ak+1 x ... x an)因为只有n-1个分割点,所以为 h(n-1)
式子2对应的模型:
先求一道题:n个元素的出栈,入栈合法方案数。
令1表示进栈,0表示出栈,则可转化为求一个2n 位、含n 个1、n 个0的二进制数,满足从左往右扫描到任意一位时,经过的0数不多于1数。显然含n 个1、n 个0的2n 位二进制数共有C(2n,n) 个,下面考虑不满足要求的数目.
考虑一个含n 个1、n 个0的2n位二进制数,扫描到第2m+1 位上时有m+1 个0和m 个1(容易证明一定存在这样的情况),则后面的0-1排列中必有n-m 个1和n-m-1 个0。将2m+2 及其以后的部分0变成1、1变成0,则对应一个n+1 个0和n-1 个1的二进制数。反之亦然(相似的思路证明两者一一对应)。
从而 C(2n,n) / (n + 1 )= C(2n,n)-C(2n, n+1) 。证毕。
以这道题为基础,有
- n对括号的匹配问题
- n个元素的出栈,入栈合法方案数。
- 有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)
- 一位大城市的律师在她住所以北n个街区和以东n个街区处工作。每天她走2n个街区去上班。如果她从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路? (因为有对角线的存在,向上走的次数如果大于向右的次数,会越过对角线)
well蛋!
参考了下: http://www.cppblog.com/MiYu/archive/2010/08/07/122573.html