偶然看到的题目,居然可以用卡特兰数解。
12个人排两排,每排都按身高由小到大排,要求第二排相应位置上每个人的身高都比第一排上的人要高,问有多少种排法?
卡特兰数的一个模型就是括号匹配。先给括号标号(序号对应身高),我们把左括号当作第一排的人,右括号当作第二排的人。
1 |
2 |
3 |
4 |
5 |
6 |
|
( |
( |
) |
( |
) |
) |
|
第一排 |
1 |
2 |
4 |
|||
第二排 |
3 |
5 |
6 |
我们可以得出括号匹配可以对应到身高排列。还要证反过来也成立。
先明确这里身高对应排列序号,合法的括号匹配就是左右括号数量一致(这里显然),并且前面的“第n个右括号之前必定至少有n左括号”。
对于每一个满足要求的身高排列,
a1 |
< |
a2 |
< |
a3 |
ʌ |
ʌ |
ʌ |
||
b1 |
< |
<>b2 |
< |
b3 |
对b1,我们知道身高小于b1的a至少有a1
对于b2,我们知道身高小于b2的a至少有a1,a2
。。。。
我们让a对应(,b对应),而括号的位置序号对应身高序号。
所以可以证明按身高排序的ai 和bi序列,替换成括号后是合法匹配。
令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 , ...)
得到式子:
式子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) 。证毕。
以这道题为基础,有
well蛋!
参考了下: http://www.cppblog.com/MiYu/archive/2010/08/07/122573.html