题目链接:https://leetcode.com/problems/super-egg-drop/

题意:给你K个鸡蛋以及一栋N层楼的建筑,已知存在某一个楼层F(0<=F<=N),在不高于F的楼层扔鸡蛋不会碎,鸡蛋碎了不能再用,没碎可以继续使用,问不论F的大小(0<=F<=N),至少需要测量多少次才能测出F的大小。题意挺好理解的,鸡蛋少的话操作肯定多点,相当于行下往上测,鸡蛋比较多就可以使用类似二分的想法了。

思路1:

  dp+二分  时间复杂度O(K*N*log N),空间复杂度O(K*N)  (自己第一次想的就是这个思路630ms,能过但是慢)

  假设我们有i个鸡蛋,我们从x层楼扔下去,如果碎了,说明F<x,相当于使用i-1个鸡蛋测量j-1层至少要测试多少次,个数加1即为答案;没碎,说明F>x,则我们使用i个鸡蛋测量x+1~N的楼层至少需要操作多少次,即N-x个楼层,下面的楼层不同考虑。二者的答案取较大的值即可。

  因此dp的思想就很明显了dp[i][j]表示使用i个鸡蛋测量j个楼层至少需要操作的次数,则dp[i][j] =min( max(dp[i-1][x-1],dp[i][j-x])+1 ,(x<=j)).

  该算法的复杂度是O(K*N^2),交上去应该会TLE

  通过观察我们可以发现dp[i-1][x-1]是随着x的增大而增大(或者不变)的(相同的鸡蛋数层数越多肯定测试次数也越多),同理dp[i][j-x]随着x的增大而减小的,而现在我们要求对于每个x,这两个数的较大值,最后再在这j个值中取一个较小值。如果是连续函数的话,就相当于求两条曲线高的那部分的最小值。如下图所示(图来自leetcode),求的是蓝色部分的最小值。所以我们可以通过二分求出二者“交点“(交点可能不存在)附近的那两个值,答案肯定是这两个值中的一个。所以降了一维,复杂度变为O(K*N*log N)。

class Solution {
public:int superEggDrop(int K, int N) {int dp[101][10001];memset(dp,0,sizeof(dp));for(int i=1;i<=K;i++)for(int j=1;j<=N;j++){dp[0][j]=1e9;dp[i][j]=1e9;int l=1,r=j;int mid;for(int k=1;k<=20;k++){mid=(l+r)/2;if(dp[i-1][mid-1]<dp[i][j-mid])l=mid;else r=mid;}if(dp[i-1][mid-1]<=dp[i][j-mid])mid++;dp[i][j]=min(dp[i-1][mid-1],dp[i][j-(mid-1)])+1;}return dp[K][N];}
};  

思路2:

  dp方程仍然是思路一中的方程,但是对于dp[i][j-x],随着j增大,最优值x的取值也会增大,即下图中的交点,既然x是非递减的,不需要每次都遍历了,因此复杂度可以减少到O(N*K)

class Solution {
public:int superEggDrop(int K, int N) {int dp[101][10001];memset(dp,0,sizeof(dp));for(int i=1;i<=K;i++){int x=1;for(int j=1;j<=N;j++){dp[0][j]=1e9;dp[i][j]=1e9;while(x<j&&max(dp[i-1][x-1],dp[i][j-x])>max(dp[i-1][x],dp[i][j-x-1]))x++;dp[i][j]=max(dp[i-1][x-1],dp[i][j-x])+1;}}return dp[K][N];}
};

  空间复杂度也可以利用循环数组降低到O(N):

class Solution {
public:int superEggDrop(int K, int N) {int dp[2][10001];memset(dp,0,sizeof(dp));int cnt=0;for(int j=1;j<=N;j++)dp[0][j] = dp[1][j] = 1e9;for(int i=1;i<=K;i++){int x = 1;for(int j=1;j<=N;j++){  while(x<j&&max(dp[cnt^0][x-1],dp[cnt^1][j-x])>max(dp[cnt^0][x],dp[cnt^1][j-x-1]))x++;dp[cnt^1][j]=max(dp[cnt^0][x-1],dp[cnt^1][j-x])+1;}cnt=cnt^1;}return dp[cnt^0][N];}
};

思路3:

  我们改变一下dp方程,dp[i][j]表示使用i个鸡蛋,j次操作,能够测量的最高楼层,假设我们采用最优策略,则对于第j次操作如果鸡蛋碎了,则需要使用i-1个鸡蛋,j-1次操作测量该层下面的楼层;如果鸡蛋没碎,则需要使用i个鸡蛋,j-1次操作测试上面的楼层,因此dp[i][j] = dp[i-1][j-1] + dp[i][j-1] + 1,我们需要找到最小的j使得dp[i][j]>=N 复杂度O(K*log N) (由于是找最小的j,因此外层循环是j)

class Solution {
public:int superEggDrop(int K, int N) {int **dp = new int *[K + 1];for (int i = 0;i <= K;i++) {dp[i] = new int[N + 1];memset(dp[i], 0, 4 * (N + 1));}for (int j = 1;j<=N;j++)for (int i = 1;i <= K;i++) {dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1] + 1;if (dp[i][j] >= N)return j;}return N;}
};  

转载于:https://www.cnblogs.com/dlutjwh/p/10793560.html

LeetCode 887. Super Egg Drop相关推荐

  1. Leetcode 1884. Egg Drop With 2 Eggs and N Floors [Python]

    细读example 2: One optimal strategy is: Drop the 1st egg at floor 9. If it breaks, we know f is betwee ...

  2. 装鸡蛋的鞋子java代码_Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)...

    887. 鸡蛋掉落 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 < ...

  3. Coursera Algorithms week1 算法分析 练习测验: Egg drop 扔鸡蛋问题

    题目原文: Suppose that you have an n-story building (with floors 1 through n) and plenty of eggs. An egg ...

  4. leetcode 372. Super Pow | 372. 超级次方(快速幂)

    题目 https://leetcode.com/problems/super-pow/ 这道题的赞踩比例,让人觉得是个大坑- 题解 快速幂,看了答案:C++ Clean and Short Solut ...

  5. LeetCode 887. 鸡蛋掉落(DP,难、不懂)

    1. 题目 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 <= F ...

  6. Leetcode 517. Super Washing Machines

    问题描述: You have n super washing machines on a line. Initially, each washing machine has some dresses ...

  7. LeetCode 887. 三维形体投影面积

    887. 三维形体投影面积 在 N * N 的网格中,我们放置了一些与 x,y,z 三轴对齐的 1 * 1 * 1 立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i ...

  8. [leetcode] 517. Super Washing Machines

    You have n super washing machines on a line. Initially, each washing machine has some dresses or is ...

  9. leetcode 517. Super Washing Machines 超级洗衣机 + 传递衣服 + 发现规律

    You have n super washing machines on a line. Initially, each washing machine has some dresses or is ...

最新文章

  1. 如何入门生信Linux
  2. IT专案管理中的风险控制。
  3. android 手机跑分,安兔兔安卓手机跑分性能榜公布:第一名实至名归?
  4. Python——[Anaconda+Jupyter Notebook+Python3.6]环境下安装face_recognition
  5. 苹果手机看python文件大小_Python练习题:你有一个目录,装了很多照片,把它们的尺寸变成都不大于iPhone5分辨率的大小...
  6. 首个使用Blazor 技术实现的社区软件 BlazorCommunity 发布
  7. cocoscreator editbox 只允许数字_用Cocos做一个数字调节框
  8. 抖音很火的失恋表白网页模板
  9. 使用函数进行邮件发送的示例
  10. androidstudio jni开发_高考失利落榜,7年Android开发现已年薪60w,我的逆袭之路想说给你听...
  11. 有的时候看项目,和创业者交流,发现他们的企业
  12. mysql 优化器_mysql之优化器、执行计划、简单优化
  13. 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第一章1-1.Fragment...
  14. 2017国民行业分类sql-存储过程_存储函数-MySQL
  15. R语言中如何查看已安装的R包
  16. 2019.03.10_2.3 -2.6
  17. 好用的局域网共享工具
  18. 高校邦HTML5,高校邦视频自动播放器
  19. JAVA代码实现计算器功能
  20. 软考中级考试信息系统管理工程师怎么样??

热门文章

  1. windows ffmpeg 推送摄像头数据到rtmp服务
  2. Ubuntu,kubuntu与xubuntu的差别 Ubuntu各版本主要差异
  3. Linux的概念与体系 7. Linux进程基础(转载)
  4. Microsoft Expression Blend 4 下载地址
  5. 百炼成钢!自己动手写一个深度学习框架!
  6. 谷歌极速人脸、手、人体姿态分析Blaze算法家族
  7. 百度刷新世界级权威DeepFake防伪数据集榜单记录,成绩超越SOTA
  8. GridMask:SOTA 数据增广方法,显著改进分类、检测、分割效果
  9. Anime4K:目前最热的开源实时动漫放大算法,Github上一周收获2600星!
  10. [高并发]Java高并发编程系列开山篇--线程实现