经典面试题楼层丢鸡蛋问题的动态规划解法与数学解法
Posted taoshiqian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典面试题楼层丢鸡蛋问题的动态规划解法与数学解法相关的知识,希望对你有一定的参考价值。
原题:
有2个鸡蛋,从100层楼上往下扔,以此来测试鸡蛋的硬度。比如鸡蛋在第9层没有摔碎,在第10层摔碎了,那么鸡蛋不会摔碎的临界点就是9层。
问:如何用最少的尝试次数,测试出鸡蛋不会摔碎的临界点?
注意:只有两个鸡蛋。第一个鸡蛋碎了,第二个鸡蛋只能挨个楼层测试了。
动态规划解法:
//height为楼层数 const int maxHeight = 100; int dp[maxHeight + 5] = { 0 }; for (int height = 1; height <= maxHeight; height++) { dp[height] = height;//最土的方法,只用第一个鸡蛋从1层开始往上试 for (int mid_h = 2; mid_h <= height; mid_h++) //第一个鸡蛋从mid_h开始丢 { // mid_h-1 第一个鸡蛋碎了,第二个鸡蛋只能挨个试mid_h-1次; // dp[height-mid_h] 第一个鸡蛋没碎,两个鸡蛋剩下只需测dp[height-mid_h]次 dp[height] = min(dp[height], 1 + max(mid_h - 1, dp[height - mid_h])); //取max之后的min,则是最坏情况下的最优解法 } } // 动态规划完毕,看看结果 for (int height = 1; height <= maxHeight; height++) { printf("%4d %4d ", height, dp[height]); }
数学解法:别人的
题目延伸:有M层楼 / N个鸡蛋,要找到鸡蛋摔不碎的临界点,需要尝试几次?
图非原创,结果如图所示。
动态规划解法:
//楼层 鸡蛋数 int dp[105][105] = { 0 }; int maxHeight = 100, maxEggs = 100; for (int height = 1; height <= maxHeight; height++) dp[height][1] = height; for (int eggs = 1; eggs <= maxEggs; eggs++) dp[1][eggs] = 1; for (int height = 2; height <= maxHeight; height++){ for (int eggs = 2; eggs <= maxEggs; eggs++){ int mid_h = 1;//第一个鸡蛋丢第一层 //dp[mid_h-1][eggs-1]碎了 , dp[height-mid_h][eggs]没碎。取max即最坏情况,再加上这一次的测试 dp[height][eggs] = 1 + max(dp[mid_h - 1][eggs - 1], dp[height - mid_h][eggs]); for (mid_h = 2; mid_h <= height; mid_h++) //第一个鸡蛋丢第mid_h层 { //最坏情况的最小测试次数 dp[height][eggs] = min(dp[height][eggs], 1 + max(dp[mid_h - 1][eggs - 1], dp[height - mid_h][eggs])); } } } //动态规划完毕,看看结果 for (int height = 1; height <= 100; height++){ for (int eggs = 1; eggs <= 2; eggs++) { printf("%4d ", dp[height][eggs]); } printf(" "); }
以上是关于经典面试题楼层丢鸡蛋问题的动态规划解法与数学解法的主要内容,如果未能解决你的问题,请参考以下文章