zoukankan      html  css  js  c++  java
  • 有一栋100层高的大楼,给你两个完全相同的玻璃球。假设从某一层开始,丢下玻璃球会摔碎。那么怎么利用手中的两个球,用什么最优策略知道这个临界的层是第几层?

    题目有一栋100层高的大楼,给你两个完全相同的玻璃球。假设从某一层开始,丢下玻璃球会摔碎。那么怎么利用手中的两个球,用什么最优策略知道这个临界的层是第几层???

     每次肯定是由低的楼层往高的楼层尝试,直到在楼层f(k),第一个球已经碎掉了,记录上一个尝试的楼层为f(k-1),在此楼层,玻璃球不会碎,所以接下来要尝试 f(k-1)+1,f(k-1)+2,f(k-3)+3, ....,知道有一个楼层碎了,这个楼层就是解啦,最坏的是到达f(k)-1 层。

      接下来的解决方案就很容易想出了:既然第一步(确定临界段)的投掷数增加不可避免,我们就让第二步(确定临界层)的投掷数随着第一步的次数增加而减少。第一步的投掷数是一次一次增加的,那就让第二步的投掷数一次一次减少。假设第一次投掷的层数是f,转化成数学模型,f+(f-1)+...+2+1就表示从f开始猜,每次的增量都比前一次的曾量减1的情况下,最后猜的那个数(即 f+(f-1)+...+2+1 ),按照提议要求f+(f-1)+...+2+1>=99,即f(f+1)/2>=99(第一次测试点选择100层是无意义的,必然会碎,所以无任何测试价值,所以第一次测试点k是1-99中的一个数),解出结果等于14。丢下第一颗鸡蛋的楼层就分别是 14 , 27 , 39 , 50 , 60 , 69 , 77 ,84 , 90 , 95 , 99 。

      前面为什么是f+(f-1)+...+2+1>=99?首先是分段确定临界段,我们要保证不管鸡蛋在哪一个临界段碎掉进行判断的次数都是一样的,所以就需要从下到上每一个段比上一个段的长度少1,同时所有段的长度总和是99(不需要是100 因为如果前面都没碎那么就一样时100了,也不需要在判断了)。

    金子分析:我来解释一个不等式右侧为什么是99呢,其实使用99还是100最后结果是一样的,只不过99说明理解的深刻,因为如果你都已经到了99层了,可以玻璃球还是没有碎,那么答案就肯定是100啦,所以100就不用猜了,如果面试的时候说一下这个99和100的关系,就说明你够聪明,至于到底用100还是99,看考官吧,不同的人理解不一样。

     首次选择14,那么最高可以判断到呢,按照上面的递减数列,14 , 27 , 39 , 50 , 60 , 69 , 77 ,84 , 90 , 95 , 99 ,102,104,105。一共是14次,最后是到105了,按照上面99和100的分析,虽然是14次猜,但是最后一个猜到了105,可知如果105还是不碎的话,那么肯定是106,106是铁定的了,不用猜了就知道,所以14次最大可以判断到106,这样15次的话就要从15开始猜,并且如果107层的话,那么需要15次。

      比如到27层,玻璃碎了,则要从15开始一层一层的尝试,比如26是解的话,那么猜的序列就是 14,27,15,16,17,18,19,20,21,22,23,24,25,26,一共14次。

    备注:这题一开始没看懂,一直在想为什么不能用二分法,二分法不是最多7次就可以搞定了吗,然后想了一会才意思到这题说的两个玻璃球是指,你最多只能用两个玻璃球来判断玻璃球碎掉临界的楼层,如果用二分法,第一步在50楼一扔碎掉了那么你这时候就糟了,你只能从第一层开始扔了,要进行50次判断,(如果你接着再在25扔,最后一颗玻璃球再碎掉你就没有球可以用了)所以二分法在这里并不好。

    这时我们只能像上面一样想用第一颗球去确定一个区间,然后在区间内从区间底部网上进行判断就可以了

  • 相关阅读:
    numpy排序函数:sort、argsort、lexsort、partition、sorted
    转载一份分类、回归、排序的评价指标
    python类的全面介绍
    好文推荐:转载一篇别人kaggle的经验分享
    实现ls -l
    C命令行参数
    C语言调用汇编
    汇编调用C程序
    linux 进程通信 :流套接字
    linux进程通信:消息队列
  • 原文地址:https://www.cnblogs.com/yunianzeng/p/12163278.html
Copyright © 2011-2022 走看看