动态规划 | 鸡蛋问题 | 元旦假期来点“蛋”题

文章目录

    • 鸡蛋掉落 - 两枚鸡蛋
      • 题目描述
      • 动态规划解法
        • 问题分析
        • 程序代码
    • 鸡蛋掉落
      • 题目描述
      • 问题分析
      • 程序代码
      • 复杂度分析

鸡蛋掉落 - 两枚鸡蛋

题目描述

原题链接

给你 2 枚相同 的鸡蛋,和一栋从第 1 层到第 n 层共有 n 层楼的建筑。

已知存在楼层 f ,满足 0 <= f <= n ,任何从 高于 f 的楼层落下的鸡蛋都 会碎 ,从 f 楼层或比它低 的楼层落下的鸡蛋都 不会碎

每次操作,你可以取一枚 没有碎 的鸡蛋并把它从任一楼层 x 扔下(满足 1 <= x <= n)。如果鸡蛋碎了,你就不能再次使用它。如果某枚鸡蛋扔下后没有摔碎,则可以在之后的操作中 重复使用 这枚鸡蛋。

请你计算并返回要确定 f 确切的值最小操作次数 是多少?

动态规划解法

问题分析

状态定义dp[i][j]表示总共有 i 层楼,现在手上有 j + 1 个鸡蛋。

状态计算dp[i][1] = min(dp[i][1], max(j, dp[i - j][1] + 1))

我们假设总共有 i 层楼,从第 j 层楼往下扔第一个鸡蛋,有两种情况:

  1. 鸡蛋碎了,那么说明f楼层一定小于j,即在第 j 层的楼下。此时的最少操作次数为j - 1 + 1 = j
  2. 鸡蛋没碎,那么说明f楼层一定大于j,即在第 j 层的楼上。接下来,我们仍然持有 2 个鸡蛋,但此时考虑的楼层数只有i - j层。此时最少操作次数为dp[i - j][1] + 1

最终从第 j 层往下扔第一个鸡蛋,所需的最少操作次数为max(j, dp[i - j][1] + 1)

我们要做的就是遍历所有可能的情况j,找到所需操作次数最小的情况。

初始化dp[i][0] = dp[i][1] = i

  • 如果手上只有 1 个鸡蛋,i 层楼至少需要操作 i 次。
  • 如果手上有 2 个鸡蛋,i 层楼的最少操作次数不超过 i 次。
程序代码
class Solution {
public:int twoEggDrop(int n) {vector<vector<int>> dp(n + 1, vector<int>(2, 0));// 初始化for(int i = 1; i <= n; i++) {dp[i][0] = i;dp[i][1] = i;}for(int i = 2; i <= n; i++) {for(int j = 1; j < i; j++) {dp[i][1] = min(dp[i][1], max(j, dp[i - j][1] + 1));}}return dp[n][1];}
};

观察上述代码,可以发现代码可以压缩成一维:

class Solution {
public:int twoEggDrop(int n) {vector<int> dp(n + 1);// 初始化for(int i = 1; i <= n; i++) {dp[i] = i;}for(int i = 2; i <= n; i++) {for(int j = 1; j < i; j++) {dp[i] = min(dp[i], max(j, dp[i - j] + 1));}}return dp[n];}
};

鸡蛋掉落

题目描述

原题链接

给你 k 枚相同的鸡蛋,并可以使用一栋从第 1 层到第 n 层共有 n 层楼的建筑。

已知存在楼层 f ,满足 0 <= f <= n ,任何从 高于 f 的楼层落下的鸡蛋都会碎,从 f 楼层或比它低的楼层落下的鸡蛋都不会破。

每次操作,你可以取一枚没有碎的鸡蛋并把它从任一楼层 x 扔下(满足 1 <= x <= n)。如果鸡蛋碎了,你就不能再次使用它。如果某枚鸡蛋扔下后没有摔碎,则可以在之后的操作中 重复使用 这枚鸡蛋。

请你计算并返回要确定 f 确切的值最小操作次数 是多少?

问题分析

如果套用上一题的分析思路,我们可以定义如下状态以及状态计算。

状态定义dp[i][j]表示总共有 i 层楼,现在手上有 j + 1 个鸡蛋。

状态计算dp[i][k] = min(dp[i][k], max(dp[j-1][k-1] + 1, dp[i - j][k] + 1)),其中k表示手上有k + 1个鸡蛋,从第 j 层开始扔鸡蛋。

但是该方法最终会 TLE

我们观察上述的状态转移方程,若我们固定鸡蛋的个数k + 1,可以发现,随着楼层数i的增加,dp[j-1][k-1] + 1这一项不会发生变动,即从第 j 层丢下的鸡蛋碎了。而dp[i - j][k] + 1这一项会随着楼层数i的增加而增加,即从第 j 层丢下的鸡蛋没碎。

接下来我们观察从第 j 层开始丢鸡蛋,随着j的增加,dp[j-1][k-1] + 1会逐渐增加,而dp[i - j][k] + 1会逐渐减小。而二者的交点位置就是dp[i][k]的最小值。

随着楼层数i的不断增加,dp[i - j][k] + 1不断上移动,而二者的交点也不断向右上方移动。

在这里插入图片描述

因此,当我们固定鸡蛋个数k+1时,随着楼层数i的不断增加,dp[i][j]最优解j的坐标也单调递增。

程序代码

class Solution {
public:int superEggDrop(int k, int n) {vector<int> dp(n + 1);// 初始化for(int i = 1; i <= n; i++) {dp[i] = i;}// 先固定鸡蛋个数for(int j = 2; j <= k; j++) {vector<int> f(n + 1);  // 存储从第x层丢下的鸡蛋没碎的历史最值int x = 1;  // 从第x楼开始抛f[0] = 0;// 总楼层数for(int i = 1; i <= n; i++) {while(x < i && max(dp[x-1], f[i - x]) >= max(dp[x], f[i - x -1])) {x++;}f[i] = 1 + max(dp[x-1], f[i - x]);}for(int i = 1; i <= n; i++) {dp[i] = f[i];}}return dp[n];}
};

复杂度分析

时间复杂度为 O ( k n ) O(kn) O(kn)

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

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

相关文章

互联网加竞赛 基于Django与深度学习的股票预测系统

文章目录 0 前言1 课题背景2 实现效果3 Django框架4 数据整理5 模型准备和训练6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于Django与深度学习的股票预测系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff…

精致旅游公司Treker网页设计 html模板

一、需求分析 旅游网站通常具有多种功能&#xff0c;以下是一些常见的旅游网站功能&#xff1a; 酒店预订&#xff1a;旅游网站可以提供酒店预订服务&#xff0c;让用户搜索并预订符合其需求和预算的酒店房间。 机票预订&#xff1a;用户可以通过旅游网站搜索、比较和预订机票…

[电磁学]猴博士不挂科

1 利用表格求场强 2 利用叠加求场强 3 利用积分求场强 电场立库仑力 球的面积公式是4πr&#xff0c;其中r为球的半径。 球的体积公式是(4/3)πr&#xff0c;其中r为球的半径。 带电物体有体积:

算法专题四:前缀和

前缀和 一.一维前缀和(模板)&#xff1a;1.思路一&#xff1a;暴力解法2.思路二&#xff1a;前缀和思路 二. 二维前缀和(模板)&#xff1a;1.思路一&#xff1a;构造前缀和数组 三.寻找数组的中心下标&#xff1a;1.思路一&#xff1a;前缀和 四.除自身以外数组的乘积&#xff…

Pytorch框架基础

参考资料 pytorch框架基础 Pycharm 页面卡住解决方案 使用ps命令结合grep来查找PyCharm相关的进程 ps aux | grep pycharm kill -9 [PID]关于怎么找这个卡住的进程&#xff0c;据初步观察&#xff0c;卡住进程打印的信息是最长的&#xff0c;此外&#xff0c;在卡住进程的打…

1、gdb基本功能

文章目录 1、gdb1.1、运行1.1.1、程序入参 1.2、断点及观察点1.2.1、设置断点1.2.2、禁用、删除断点1.2.3、观察点 1.3、打印1.3.1、设定打印参数1.3.2、打印数据1.3.3、自动打印1.3.4、按照地址打印 linux下我现在接触到的常用调试工具如下. gbdgdbguicmake-tools gdb是最为通…

冠赢互娱基于 OpenKrusieGame 实现游戏云原生架构升级

作者&#xff1a;力铭 关于冠赢互娱 冠赢互娱是一家集手游、网游、VR 游戏等研发、发行于一体的游戏公司&#xff0c;旗下官方正版授权的传奇类手游——《仙境传奇》系列深受广大玩家们的喜爱。基于多年 MMORPG 类型游戏的自研与运营经验&#xff0c;冠赢互娱正式推出了 2D M…

链表精选题集

目录 1 链表翻转 题目链接&#xff1a; 解题&#xff1a; 试错版&#xff1a; 2 找中间节点 题目链接: 题解&#xff1a; 3 找倒数第k个节点 题目链接&#xff1a; 题解&#xff1a; 4 将两个升序链表合并为一个升序链表 题目链接&#xff1a; 题解&#xff1a; …

【HarmonyOS开发】案例-记账本开发

OpenHarmony最近一段时间&#xff0c;简直火的一塌糊度&#xff0c;学习OpenHarmony相关的技术栈也有一段时间了&#xff0c;做个记账本小应用&#xff0c;将所学知识点融合记录一下。 1、记账本涉及知识点 基础组件&#xff08;Button、Select、Text、Span、Divider、Image&am…

计算机网络——计算大题(七)

前言&#xff1a; 最近也是在准备计算机考试&#xff0c;我们的考试形式是上机考试&#xff0c;所以可能有些计算题是会给提供思路的&#xff0c;前面已经对本学期的计算机网络知识有了一个简单的认识与了解&#xff0c;现在我们就来对计算大题进行一个学习吧&#xff0c;这里的…

WEB 3D技术 three.js 雾 基础使用讲解

本文 我们说一下 雾 在three.js中有一个 Fog类 它可以创建线性雾的一个效果 她就是模仿现实世界中 雾的一个效果 你看到远处物体会组件模糊 直到完全被雾掩盖 在 three.js 中 有两种雾的形式 一种是线性的 一种是指数的 个人觉得 线性的会看着自然一些 他是 从相机位置开始 雾…

二级路由的配置以及注意项

二级路由 比如说LayOut组件是父亲&#xff0c;LayOut和ArtComp是儿子&#xff0c;那我们怎么给儿子配路由呢&#xff1f; 1、首先在router下的index.js导入组件&#xff0c;配置规则&#xff0c;详细如下 // 导入路由相关组件 import LayOut from /views/LayOut import UserC…