买票找零问题——卡特兰数的应用

今天遇到了一道题目,大致是说:

有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?


我摔。。。哪有这么多刚好,其实这题完全可以变种成另一种表达形式:

有n对左括号和右括号,现在问到底有多少中括号合法匹配的组合。

感觉清爽了很多。
那我们现在来求解一下到底有多少中括号合法匹配的组合。


解决方案:

原理

实际上,这个就是卡特兰数的一个应用:

其前几项为 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …

令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(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2
h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5

另类递推式[2] :

h(n)=h(n-1)*(4*n-2)/(n+1);

递推关系的解为:

h(n)=C(2n,n)/(n+1) (n=0,1,2,…)

递推关系的另类解为:

h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,…)

应用

我们现在就应用 h(n)=C(2n,n)/(n+1)(n=0,1,2,...)  求解我们的找零问题(括号匹配问题)。

我们把右括号设为状态‘1’,左括号设为状态‘0’。2n个数的排序对应n个1和n个0组成的2n位二进制数。当一个右括号参与到匹配当中时,我需要保证这个右括号之前的括号序列当中至少有一个悬空的左括号,因此可行解的总数目等于由左而右扫描由n个1和n个0组成的2n位二进制数,在这个扫描过程当中1的累计数不小于0的累计数的方案种数。

在2n位二进制数中填入n个1的方案数为c(2n,n)(位置在1被确定以后,0的位置会被自动确定)。在这些c(2n,n)个方案中减去不符合要求(由左而右扫描,在这个扫描过程当中0的累计数大于1的累计数)的方案数目,随即我们得到了最后的解。

不符合要求的解的特征是由左而右扫描时,必然在某一奇数位2m+1位上首先出现m个0的累计数和m+1个1的累计数(又前提条件下,有m个0,m个1,故可知,接下来的序列当中还能找到n-m个0和n-m-1个1),如若把这2m+1位上的0和1互换,使之成为m+1个0和m个1,结果得1个由n+1个0和n-1个1组成的2n位数,即一个不合要求的数对应于一个由n+1个0和n-1个1组成的排列。

反过来,任何一个由n+1个0和n-1个1组成的2n位二进制数,由于0的个数多2个,2n为偶数,故必在某一个奇数位上出现0的累计数超过1的累计数。同样在前面部分0和1互换,使之成为由n个0和n个1组成的2n位数,即n+1个0和n-1个1组成的2n位数必对应一个不符合要求的数。

因而不合要求的2n位数与n+1个0,n-1个1组成的排列一一对应。

显然,不符合要求的方案数为c(2n,n+1)。由此得出输出序列的总数目= c(2n,n) - c(2n,n+1) = c(2n,n) / (n+1) = h(n)。

你可能感兴趣的:(笔试,math)