本文由 @lonelyrains 出品。转载请注明出处。
文章链接: http://blog.csdn.net/lonelyrains/article/details/46428569
网上非常多资料,但我感觉都不太易懂,每一步的推导是为什么。
所以我这里仅仅想写一种比較简单、比較完整的推演流程。
题目描写叙述: (挑了一个比較严谨的描写叙述。问题描写叙述严谨非常重要。不然会影响解题思路)
一幢 100 层的大楼,给你两个鸡蛋. 假设在第 n 层扔下鸡蛋,鸡蛋不碎,那么从前 n-1 层扔鸡蛋都不碎.
这两仅仅鸡蛋一模一样,不碎的话能够扔无数次. 已知鸡蛋在0层扔不会碎.
提出一个策略, 要保证能測出鸡蛋恰好不会碎的楼层,
并使此策略在最坏情况下所扔次数最少.
问题分析:
1)最坏情况下所扔次数最少。比較绕口。想表达的意思是。在不明白知道哪一层会碎的情况下。要找到一种策略,通过最少的试验次数,得到临界楼层(恰好不会碎的楼层)。不明白知道。就须要考虑最糟糕的情况,并且这样的策略与其它策略相比是最糟糕的情况下,最少的试验次数。
2)假设一种扔法:第一个鸡蛋,从50楼扔下去。
假设碎了,第二个鸡蛋必须从1~49层逐层试验。假设第i层为临界层。且i≤49,这个时候,要试验的总次数是1 +(i - 1)。由于必须保证在没找到临界楼层之前,鸡蛋不能碎。假设没碎,则第一个鸡蛋能够接着从75层扔。
由于即使这次碎了,还有个鸡蛋,能够继续逐层试验。对第一个鸡蛋的继续从中间分,就比較合理。
3)假设到代数:假设第一枚鸡蛋扔下去的层数为i,则碎了的情况,须要扔的总次数最糟糕的情况是1 + ( i - 1 );假设没碎,剩下的两个鸡蛋都在,须要扔的次数一定为1 + 用两枚鸡蛋来解决剩下的100 - i层的次数(这个问题跟原题是一样的。可是层数少了一些)。也就是 假设用f ( 100 )表示100层的最坏情况下的最少次数,那么从第i层扔鸡蛋的最糟糕的试验次数是 1+ Max( i - 1, f ( 100 - i ) ),Max表示这两者之间的最大值,是最最糟糕的情况了。
而 f ( 100 ) 就是对全部从1到100的全部i里。 1+ Max( i - 1, f ( 100 - i ) )的值最小的那个。
4)迭代公式: f ( 100 ) = Min ( 1 + Max ( i - 1, f (100 - i ) ) ) . 当中Max是针对的 i-1、 f ( 100 - i ) 两者 。 而Min是针对的全部的从1到100的i。
5)初始状态: 假设有一层,从第一层扔下去,无论碎不碎。最糟糕的情况也仅仅须要推断一次。 即 f ( 1 ) = 1。而如题所述,第0层不会碎,则 不用扔也知道,即f(0) = 0。
6)终于结论:题目变成了分析一个迭代公式的值。翻译成了计算机语言,剩下的就能够交给计算机了。
不须要知道怎么一步步算,这不应该是人干的事。仅仅须要知道已经变成了能够循环递归的算式,能够交给计算机即可了。
// 实现代码 <a target=_blank href="http://blog.csdn.net/lonelyrains">blog.csdn.net/lonelyrains</a> #include <stdio.h> // #define MAX((a),(b)) (a)>(b)?(a):(b) //注意这里也是常考的一点,应该写成以下的形式 #define MAX(a,b) ((a)>(b)?(a):(b)) int fun ( int layer ) { if ( layer <= 0 ) { return 0; } if ( layer == 1 ) { return 1; } int min = layer; // 一栋layer层的大楼试验次数肯定不可能超过layer次。 int temp; for ( int i = 1; i <= layer; i++ ) { temp = 1 + MAX(i-1, fun( layer - i ) ); if( min > temp ) min = temp; } return min; } int main() { int layer = 19; printf("%d",fun(layer)); return 0; }
7)其它扩展:
① 问题的解法不止这一种描写叙述,并且不一定要交给计算机算。由于这样递归算。计算机要累死了。能够优化到用非常easy的数列求和公式得到。
关于怎么来的,有两种思路。能够參考以下的第二个參考链接给出的基于意义的理解。这是一种思路。可是比較难理解。第二种。就是纯粹的组合数学方法。将迭代公式转换成通项公式,这个问题还没找到有人这样写过,可是绝对能够有。
② 问题能够扩展为一栋n层的大楼,有m个鸡蛋。甚至不止一栋,而是p栋。 无论怎么样扩展,问题都能够归为找迭代公式。
这个思路就是动态规划的精髓。
8)參考链接: