一道有趣的木板问题

前些日子在网上闲逛,看到一个有趣的木板问题,和同学交流一番,略有心得,就把我的解法写出来分享。

题目是这样的,有N块木板,高低均不相同,但因为会互相遮挡,按高矮不同的组合从左右分别看过去可以看到不同的木板数,求从左边看上去有L块,右边看上去有R块的组合数。

 

 
如这个图,木板总共有9块,从左边看上去能看到4块,从右边看过去能看到3块。
 
解题思路与方法:
1、首先,这是一个组合数学问题。显然,最高的一块木板无论怎么摆都会被左右两边同时看到,因此,若所有木板都没有被遮挡的情况下,左右两边能看到的模板的最大数量为N+1块,因此,当L+R>N+1时,问题无解,即所求组合数为0,同时,若L<=0或者R<=0同样无解。
 
2、现在讨论有解的情况,因为最高的一块肯定能被看到,除去最高一块之外,左边至少需要L-1块木板,右边至少需要R-1块木板,所以可自由分配的木板的个数为N-1-(L-1+R-1)=N-L-R+1,即左边木板的取值范围是(L-1,N-R),相应的,右边为(R-1,N-L)。
 
3、有x块木板,从一个个固定方向看上去,只能看到y块的组合数,形式化定义为f(x,y),由2可知,整个问题的组合数可以表示为:(没有数学公式编辑器真蛋疼)
 
含义就是,给左边分配i块木板,让它看上去可以看到L-1块,同时给右边分配N-i块板(公式打错了,懒得改了),让他看上去是R-1块。为啥是L-1和R-1呢?因为最高的那块肯定是要被看到的,两边共享,除去最高的那块,实际上两边只需要看到L-1和R-1块就行了。因为排列组合中的乘法原理,所以二者相乘而不是相加,同时枚举木板的所有可能取值,也就是那个求和符号。
 
4、现在的问题是,如何求f这个函数的解。这里的方法是,尝试把f变换成一个递归定义的函数,然后通过求解递归式的方法进行求解。
对于函数f(x,y),易知,当x=y时,f(x,y)=1,即共有x块木板,要看到x块,唯一的排列方式是按从低到高排列,只有这样木板才不会互相遮挡全部看到。
当x
当y>x时,先定义全排列函数A(x,y)也就是从y中取x得全排列,然后可以得到
 
这个公式怎么理解呢?简而言之就是,i代表最高的木板后面有多少木板,显然,这些木板会被挡住而看不见,以x=4,y=6来描述吧,即所求的是,总共有6块木板,要从一侧看上去只能看到4块,它的排列有多少种。
当i=0时,即最高的木板后面没有任何木板,此时问题变成,总共5块木板,从一侧看上去只有3块的组合数,即f(3,5)。
当i=1时,即最高的木板后面有一块木板,首先先选出除了最高木板那块之外,剩下的模板中到底那块木板会放在最高木板之后,即A(1,5)=5,其次问题变成还剩下4块木板(最高的和最高的后面挡住那块给去除掉),要看上去只能看到3块,即f(3,4)。
当i=2时,最高木板后面放两块,其余同i=1。
 
 
5、这样把f用递归的形式表示出来,然后再求解一介递归式,带入第三步的公式,额,貌似形式不是很直观,这里就不写了。

你可能感兴趣的:(算法与数学)