问题描述:
编号为1,2,3,...,n1,2,3,...,n1,2,3,...,n的车厢被拖入堆栈,并可以在任何时候将它拖出。问车厢出栈的方式共有多少种?
问题分析1:
编号为1,2,3,...,n1,2,3,...,n1,2,3,...,n的车厢被拖入堆栈,并可以在任何时候将它拖出。例如,n=3,分别有5种出栈方式:123,132,213,231,321。而排列312是不可能发生的,因为堆栈的LIFO原则。
编号为1,2,3,...,n1,2,3,...,n1,2,3,...,n的车厢被压入堆栈,设其出栈序号为P1,P2,...,PnP_1,P_2,...,P_nP1,P2,...,Pn,则对任意的PiP_iPi,其后面的序号Pi+1,...,PnP_{i+1},...,P_nPi+1,...,Pn比PiP_iPi小的编号必逆序。
例如,n=5,125346是不可能发生的。
利用递归分治的思想,可以把问题分为两个部分,一个是第iii辆车出栈之前的车,一个是第iii辆车之后的车;前者有iii辆,后者有n−i−1n-i-1n−i−1辆。由乘法原理和加法原理,F(n)=F(0)F(n−1)+F(1)F(n−2)+F(2)F(n−3)+⋯+F(n−1)F(0)F(n)=F(0)F(n-1)+F(1)F(n-2)+F(2)F(n-3)+\cdots+F(n-1)F(0)F(n)=F(0)F(n−1)+F(1)F(n−2)+F(2)F(n−3)+⋯+F(n−1)F(0).
验证一下(F(0)=1F(0)=1F(0)=1),
F(1)=F(0)F(1)=1F(1)=F(0)F(1)=1F(1)=F(0)F(1)=1
F(2)=F(0)F(1)+F(1)F(0)=2F(2)=F(0)F(1)+F(1)F(0)=2F(2)=F(0)F(1)+F(1)F(0)=2
F(3)=F(0)F(2)+F(1)F(1)+F(2)F(0)=5F(3)=F(0)F(2)+F(1)F(1)+F(2)F(0)=5F(3)=F(0)F(2)+F(1)F(1)+F(2)F(0)=5
是正确的。
问题分析2:
问题可以化为,所有组合的总数−-−不符合要求的组合的总数.
首先,每一种进出栈的顺序和车编号是一一对应的,如出栈顺序为14532,设进栈为+1,出栈为-1,则进出栈顺序为+1,−1,+1,+1,+1,−1,+1,−1,−1,−1+1,-1,+1,+1,+1,-1,+1,-1,-1,-1+1,−1,+1,+1,+1,−1,+1,−1,−1,−1.显然,进栈和出栈的次数都是相同的。
故,对n辆列车,进栈和出栈都分别是n次,则:
所有进栈和出栈的组合总数为C2nnC_{2n}^{n}C2nn.
下面求不符合要求的组合的数目:
在第一次不符合要求的出栈之后,将它之前的所有项都全部取相反数(包括它),例如,无效组合N={+1,−1,+1,−1,−1,⋯ }N=\{+1,-1,+1,-1,-1,\cdots\}N={+1,−1,+1,−1,−1,⋯},将它取相反数变为M={−1,+1,−1,+1,+1,⋯ }M=\{-1,+1,-1,+1,+1,\cdots\}M={−1,+1,−1,+1,+1,⋯},则+1项出现次数变为n+1n+1n+1,-1项出现次数变为n−1n-1n−1,由于取相反数前后的集合N→MN\rightarrow MN→M是一个一一映射,所以无效组合的总数为C2nn−1C_{2n}^{n-1}C2nn−1.
所以,车厢出栈的方式有C2nn−C2nn−1=C2nn/(n+1)C_{2n}^{n}-C_{2n}^{n-1}=C_{2n}^{n}/(n+1)C2nn−C2nn−1=C2nn/(n+1)种。
扩展:卡特兰数
F(n)=F(1)F(n−1)+F(2)F(n−2)+⋯+F(n−1)F(1).F(n)=F(1)F(n-1)+F(2)F(n-2)+\cdots+F(n-1)F(1).F(n)=F(1)F(n−1)+F(2)F(n−2)+⋯+F(n−1)F(1).
类似问题:
1.买票问题:
有m+n个人买票(m>n),m个人手持的是50美分,n个人手持的是1美元,刚开始时售票处没有零钱来找零,问有多少种排队方式能保证每个人都买到票且不会因为没有找零而耽误时间?
设手持50美分的为+1,手持1美元的为-1
总的组合数为Cm+nnC_{m+n}^{n}Cm+nn
第一次发现无效组合时,例如+1,−1,−1,⋯+1,-1,-1,\cdots+1,−1,−1,⋯,将其取相反数,−1,+1,+1,⋯-1,+1,+1,\cdots−1,+1,+1,⋯,其中+1项有m+1个,-1项有n-1个,则无效组合数为$C_{m+n}^{n-1} $
所以,排队方式有Cm+nn−Cm+nn−1=(m+1−n)(m+n)!(m+1)!n!=m+1−nmCm+nnC_{m+n}^{n}-C_{m+n}^{n-1}=\frac{(m+1-n)(m+n)!}{(m+1)!n!}=\frac{m+1-n}{m}C_{m+n}^{n}Cm+nn−Cm+nn−1=(m+1)!n!(m+1−n)(m+n)!=mm+1−nCm+nn种.
2.走m×nm\times nm×n的网格:从原点到点(m,n)(m,n)(m,n),每次要么往上要么往右走,问y=xy=xy=x下方(包括边界)共有多少条路径?
3.给定n个节点,能构成多少种不同的二叉树?