leetcode887. 鸡蛋掉落(动态规划-java)

鸡蛋掉落

  • leetcode887. 鸡蛋掉落
    • 题目描述
    • 暴力递归 + 二分查找
      • 代码演示
    • 动态规划
      • 代码演示
  • 动态规划专题

leetcode887. 鸡蛋掉落

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/super-egg-drop

题目描述

给你 k 枚相同的鸡蛋,并可以使用一栋从第 1 层到第 n 层共有 n 层楼的建筑。
已知存在楼层 f ,满足 0 <= f <= n ,任何从 高于 f 的楼层落下的鸡蛋都会碎,从 f 楼层或比它低的楼层落下的鸡蛋都不会破。
每次操作,你可以取一枚没有碎的鸡蛋并把它从任一楼层 x 扔下(满足 1 <= x <= n)。如果鸡蛋碎了,你就不能再次使用它。如果某枚鸡蛋扔下后没有摔碎,则可以在之后的操作中 重复使用 这枚鸡蛋。
请你计算并返回要确定 f 确切的值 的 最小操作次数 是多少?

示例 1:
输入:k = 1, n = 2
输出:2
解释:
鸡蛋从 1 楼掉落。如果它碎了,肯定能得出 f = 0 。
否则,鸡蛋从 2 楼掉落。如果它碎了,肯定能得出 f = 1 。
如果它没碎,那么肯定能得出 f = 2 。
因此,在最坏的情况下我们需要移动 2 次以确定 f 是多少。

示例 2:
输入:k = 2, n = 6
输出:3

示例 3:
输入:k = 3, n = 14
输出:4

提示:
1 <= k <= 100
1 <= n <= 10000

暴力递归 + 二分查找

这道题要用动态规划解,但题目本身很难直接推出动态规划的状态转移方程。
所以先用暴力递归尝试写出暴力版本。不过用缓存加二分查找优化后,效率还是可以的,

递归时,首先要考虑的就是递归过程中的变量,这题很容易发现变化的是鸡蛋的个数和楼层,选中一个楼层扔鸡蛋,没破的话呢就去上面楼层继续测试,(鸡蛋个数K 不变,楼层变成n - i):
process(n - i,k);
鸡蛋破了的话,要去下面楼层继续测试:鸡蛋个数减一,楼层减一
process(i - 1,k - 1).
用一个图演示,就容易看懂了:
在这里插入图片描述
我们先取每个楼层的最差情况,然后选取中所有楼层最差情况下的最好情况,就是需要最少的次数了。

然后再看下为什么可以进行二分查找,首先找到,要进行二分查找,必须要满足具有单调性,首先想这样一个问题,如果鸡蛋个数固定时,楼层越多,需要测试的次数就越多,因此这个递归具有单调性,
process(n - i,k); i 越大,值会越小,
process(i - 1,k - 1). i 越大值也会越大,
如图演示:
在这里插入图片描述
其实就是求交点。

代码演示

   public int superEggDrop(int k, int n) {int[][]dp = new int[n + 1][k + 1];return process(n,k,dp);}/*** 递归加 二分优化*/public static int process(int n,int k,int[][]dp){if(n == 0){return 0;}if(k == 1){return n;}//缓存if(dp[n][k] != 0){return dp[n][k];}int res = Integer.MAX_VALUE;int l = 1;int r = n;while(l <= r){int mid = (l + r) / 2;//没碎int p1 = process(n - mid,k,dp);//碎了int p2 = process(mid - 1,k - 1,dp);if(p2 > p1){r = mid - 1;res = Math.min(res,p2 + 1 ) ;}else{l = mid + 1;res = Math.min(res,p1 + 1);}}dp[n][k] = res;return res;}

动态规划

动态规划时,我们换一个思路去做。
就是我们知道鸡蛋个数和面对的楼层时,就知道最小的扔鸡蛋次数,我们最终要的答案就是dp(k,n).
现在我们修改下dp的含义,确定鸡蛋个数和最多允许的扔鸡蛋次数,就能确定楼的最高层数,具体就是:
dp[k][m] = n;
当前有k个鸡蛋,最多可以尝试扔m次。
比如dp[1][7] = 7
表示一个鸡蛋,最多扔七次,这个状态下楼层最高七层,
这样我们可以得出另外一个状态转移方程:
dp[k][m] = dp[k][m - 1] + dp[k - 1][m - 1] + 1;
如图演示:
在这里插入图片描述
dp[k][m - 1]就是上面的楼层数,因为鸡蛋没碎,才可以上去,鸡蛋个数不变,扔鸡蛋次数减一。
dp[k - 1][m - 1],就是楼下的层数,鸡蛋碎了去楼下,k -1,扔鸡蛋的次数 m - 1.
最后加1 ,加上本身楼层。
根据这个状态转移方程就可以写代码了。

代码演示

/**
* 动态规划
*/public int superEggDrop7(int k, int n) {int[][]dp = new int[k + 1][n + 1];int m = 0;//楼层 == n 时,退出,while(dp[k][m] < n){m++;for(int i = 1; i <= k;i++){dp[i][m] = dp[i][m - 1] + dp[i - 1][m - 1] + 1;}}//m 扔的次数。return m;}

动态规划专题

leetcode1884. 鸡蛋掉落-两枚鸡蛋

leetcode72. 编辑距离

leetcode1049. 最后一块石头的重量 II

leetcode312. 戳气球

leetcode63. 不同路径 II

leetcode62. 不同路径

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/696.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

助力工业物联网,工业大数据之其他维度:组织机构【十五】

文章目录 01&#xff1a;其他维度&#xff1a;组织机构02&#xff1a;其他维度&#xff1a;仓库、物流附录一&#xff1a;常见问题1.错误&#xff1a;没有开启Cross Join2.错误&#xff1a;Unable to move source 01&#xff1a;其他维度&#xff1a;组织机构 目标&#xff1a;…

Linux 设备驱动程序(四)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核 Linux 设备驱动程序&#xff08;一&#xff09; Linux 设备驱动程序&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;三&#xff09; Linux 设备驱动程序&#xff08;四&#xff09; Linux设备驱动开发详解 …

IntelliJ IDEA如何自动生成serialVersionUID

IntelliJ IDEA如何自动生成serialVersionUID&#xff1f; 实体对象在流中传输时&#xff0c;需要将其序列化。 对象的类型实现Serializable接口public class ClassName implements java.io.Serializable { } 生成版本号serialVersionUID单击类名&#xff0c;按Alt Enter,在出…

【单目标优化算法】杂草优化算法(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …

DragGAN开源:生成图像流形上的基于点的交互式操作

文旨在解决生成对抗网络&#xff08;GAN&#xff09;中控制生成图像的问题。通过“拖动”图像中的任意点&#xff0c;实现用户交互式精确控制生成图像的姿态、形状、表情和布局。 这个名叫DragGAN的模型&#xff0c;本质上是为各种GAN开发的一种交互式图像操作方法。论文以Sty…

软件外包开发在线监控工具

软件系统上线后需要实时监控&#xff0c;这样在系统出现问题后可以及时发现问题并解决问题。今天和大家分享常见的软件系统监控工具&#xff0c;这些工具功能强大且成熟稳定&#xff0c;熟练的应用可以帮助运维人员解决很多项目中的实际问题。北京木奇移动技术有限公司&#xf…

java面试高频面试题

文章目录 面向对象 什么是面向对象&#xff1f;封装继承多态 和equals比较hashCode与equals重载和重写的区别Final类加载器spring是什么AOP的理解谈谈你对IOC的理解零拷贝RocketMQ 架构设计RocketMq 事务消息原理RockeMq顺序消息消费原理简述RockerMQ持久化机制RocketMQ如何保…

Redis的简单使用 (实现Session持久化)

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、Redis数据类型的使用 1. 字符串&#xff…

“前端已死”

一、一些迹象 逛社区&#xff0c;偶然看到了这张图片&#xff1a; 嗯……我眉头一皱&#xff0c;久久不语&#xff0c;心想&#xff0c;有这么夸张吗&#xff0c;假的吧&#xff1f; 突然想到&#xff0c;最近我在社区发了个前端招聘的信息&#xff0c;结果简历漫天纷飞&…

并发-JMM-CPU缓存一致性协议MESI

回顾 指令重排 第一V读&#xff0c;都不能指令重排&#xff1b;第二个V写&#xff0c;都不能指令重排 普通读写&#xff0c;写读都会发生指令重排&#xff0c;V写普通读写会发生指令重排&#xff0c;普通读写V读会发生指令重排 CPU缓存一致性协议MESI java—》cpu的执行过程…

kafka基础

文章目录 1、什么是消息队列&#xff1f;2、基础架构3、Kafka为什么快4、零拷贝5、Rebalance机制6、kafka如何避免重复消费7、避免消息丢失8、Kafka怎么实现消息的顺序消费9、什么是ISR10、Kafka文件存储机制 1、什么是消息队列&#xff1f; kafka是一个消息队列的中间件&…

MySQL - 数据库级别的外键

1. 外键 FOREIGN KEY (了解) 测试数据 &#xff1a; 学生表 CREATE TABLE IF NOT EXISTS student (id INT(4) NOT NULL AUTO_INCREMENT COMMENT 学号,name VARCHAR(30) NOT NULL DEFAULT 匿名 COMMENT 姓名,pwd VARCHAR(20) NOT NULL DEFAULT 123456 COMMENT 密码,sex VARC…