zoukankan      html  css  js  c++  java
  • 排列木桩

    原题

    有N个木桩,高度分别为1到N。你现在要将木桩排列为一行,当你从左边看的时候,只看到L个木桩(因为,一些高的木桩会挡住矮的木桩);从右边看时,只看到R个木桩。给定N、L、R,你该如何排列木桩呢?

    例1:N=3,L=2,R=1,可行的排列方案只有{2,1,3}。

    例2:N=3,L=2,R=2,可行的排列方案有{1,3,2}{2,3,1}

    分析

    开始排列木桩的时候,应该如何选取第一根木桩呢?一个很直接的选择就是先确定最高的木桩的位置,也就是N。因为,无论从左到右,还是从右到左看,都要到最高停下来。

    确定了最高的木桩之后,无论从哪一边看,都至少有一个木桩。接下来,该如何处理?想必大家已经想到了,开始递归呗。左右两边,也同样是先确定最高的木桩的位置,依次递归下去。

    构造的方法,是比较简单地。但,往往这个时候面试题并没有结束。面试官,会进一步问:给定NLR,有多少种排列木桩的方法呢?从一个构造问题,转变为一个计数的问题。该如何做呢?方法仍旧是递归,我们尝试写出递归表达式。

    假设,b(N,L,R)表示排列方案的总数。f(N, L)表示N个木桩,排列得到从左边能够看到L个木桩的方案总数。我们从f的递归形式入手分析。

    首先,f(N,N)=1。从左到右,从低到高排列,只有一个方案。

    然后,f(N,M)=0,当N< M时。显而易见。

    其次,f(N,1)=(N-1)!。当只看到一个木桩的时候,即最高的木桩排在最左边,其他的木桩无论怎么排列都可以。

    再次,假设最高的木桩放在从左边开始的第k个位置,则,我们要在剩下的N-1个木桩里面,选取k-1个木桩放在最高木桩的左边,并且,找到能看到L-1个木桩的方案数(因为最高的木桩一定能看见,所以是L-1个),此时剩下的N-K个木桩,可以任意排列,得到递归表达式如下:

    f(N, L) = sum_{L<=k<=N} (N-1 选择 k-1) * f(k-1, L-1) * (N-k)!

    这个式子,是仅仅考虑了总左边看到L个柱子的情况,再需要考虑,从右边看,有R根柱子的方案呢?其实很简单了,剩下的N-k个柱子,不要任意排列,要保证从右边能够看到R-1个柱子即可。所得递归式如下:

    b(N,L,R) = sum_{L<=k<=N-R+1} (N-1 选择 k-1) * f(k-1, L-1) * f(N-k,R-1)

    如何?并不是很难的题目,只要抓住从哪根木桩开始即可。

    其实,这个题目从最矮的木桩开始,也可以写出漂亮、而且更简单递归表达式的。简单提示:

    *何时能够看到最矮的木桩?*看到了如何?*看不到,又如何?

    【分析完毕】

  • 相关阅读:
    jquery,日常 记录知识 点 (选择器的引用类型)
    jQuery之map()和get() map().get().join意思
    转 谈谈JS里的{ }大括号和[ ]中括号的用法,理解后就可以看懂JSON结构了。
    CSS属性
    CSS3属性
    写网页的随意 记录要点
    css,查询相应标签,div等
    CSS ,浮动,clear记录,和一些转载别处
    linux下如何关闭防火墙?如何查看防火墙当前的状态
    Objective-C和Swift混合编程开发
  • 原文地址:https://www.cnblogs.com/downtjs/p/3534988.html
Copyright © 2011-2022 走看看