首页 > 其他分享 >Leetcode 887. 鸡蛋掉落

Leetcode 887. 鸡蛋掉落

时间:2024-09-29 12:47:53浏览次数:11  
标签:状态 right 掉落 result1 楼层 887 Leetcode dp left

1.题目基本信息

1.1.题目描述

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

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

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

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

1.2.题目地址

https://leetcode.cn/problems/super-egg-drop/description/

2.解题方法

2.1.解题思路

对1到n的x个位置,如果x处碎了,则找下面的x-1段的最小操作数dp[x-1],同时次数的蛋只剩下k-1个;如果x处蛋没碎,则找上面的n-x段的的操作数dp[n-x],此时剩余蛋还是k个。最终获取所有x中最小的步数。

2.2.解题步骤

第一步,状态定义,这里的状态函数的方式,因为状态转移时即会用到大的n状态,也会用到小的n的状态。其中状态函数的输入值为剩余鸡蛋数k和待查找的楼层层数,返回该状态下的得到分界楼层f的最小步数。

第二步,递归进行状态转移。上下两段楼层的步骤是分别是一个随当前楼层x的递减函数dp(k,n-x)和递增函数dp(k-1,x-1),所以可以用二分法找到上下两段楼层中最大的步骤数的最小值。同时使用字典记忆每个已经获取的状态的值,减小程序开销。最终的dp(k,n)即为题解。

3.解题代码

Python代码

class Solution:
    # 对1到n的x个位置,如果x处碎了,则找下面的x-1段的最小操作数dp[x-1],同时次数的蛋只剩下k-1个;如果x处蛋没碎,则找上面的n-x段的的操作数dp[n-x],此时剩余蛋还是k个。最终获取所有x中最小的步数。
    # 第一步,状态定义,这里的状态函数的方式,因为状态转移时即会用到大的n状态,也会用到小的n的状态。其中状态函数的输入值为剩余鸡蛋数k和待查找的楼层层数,返回该状态下的得到分界楼层f的最小步数。
    # 第二步,递归进行状态转移。上下两段楼层的步骤是分别是一个随当前楼层x的递减函数dp(k,n-x)和递增函数dp(k-1,x-1),所以可以用二分法找到上下两段楼层中最大的步骤数的最小值。同时使用字典记忆每个已经获取的状态的值,减小程序开销。最终的dp(k,n)即为题解。
    def superEggDrop(self, k: int, n: int) -> int:
        # dp(k,n)为k个鸡蛋的情况下,n层楼需要的最小操作次数(注意:这里的n层楼可以从中间的开始)
        memo={}
        def dp(k,n):
            if (k,n) not in memo:
                if n==0:
                    result1=0
                elif k==1:
                    result1=n
                else:
                    left,right=0,n+1  # 左开右开区间
                    while left+1<right:
                        x=(right-left)//2+left
                        val1=dp(k-1,x-1)    # x的递增函数
                        val2=dp(k,n-x)  # x的递减函数
                        # 求最后一个val1小于val2对应的x
                        # 红:val1<=val2的x,蓝:val1>=val2的x;left始终指向红,right始终指向蓝(相等的数特殊处理,同时给予红蓝属性)
                        if val1<val2:
                            left=x
                        elif val1>val2:
                            right=x
                        else:
                            left=right=x
                    # 此时right指向最后一个val1<val2的x,left指向第一个val1>=val2的x
                    # result1=1+min(dp(k,n-right),dp(k-1,left-1))
                    result1=1+min(max(dp(k - 1, x - 1), dp(k, n - x))
                                  for x in (left, right))
                memo[(k,n)]=result1
            return memo[(k,n)]
        return dp(k,n)

4.执行结果

在这里插入图片描述

标签:状态,right,掉落,result1,楼层,887,Leetcode,dp,left
From: https://www.cnblogs.com/geek0070/p/18439461

相关文章

  • (nice!!!)LeetCode 2286. 以组为单位订音乐会的门票(线段树)
    题目:2286.以组为单位订音乐会的门票思路:线段树做法。(线段树)acwing1265.数星星classBookMyShow{public: //结构体typedefstructNode{intmn=0;//最小空位编号longlongsum=0;//非空位置之和}node; //n,mintN,M;......
  • leetcode74 搜索二维矩阵
    leetcode74搜索二维矩阵思路可以使用二叉搜索,首先先看标准的闭区间二叉搜索代码publicintqSearch(int[]a,intl,intr,inttarget){intmid=(l+r)/2;if(l>r)returnl;//终止条件,区间为空if(a[mid]==target)returnmid;elseif(a[mid]<target)retur......
  • Leetcode 1235. 规划兼职工作
    1.题目基本信息1.1.题目描述你打算利用空闲时间来做兼职工作赚些零花钱。这里有n份兼职工作,每份工作预计从startTime[i]开始到endTime[i]结束,报酬为profit[i]。给你一份兼职工作表,包含开始时间startTime,结束时间endTime和预计报酬profit三个数组,请你计算并返回可......
  • Leetcode面试经典150题-64.最小路径和
    给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。示例1:输入:grid=[[1,3,1],[1,5,1],[4,2,1]]输出:7解释:因为路径1→3→1→1→1的总和最小。示例2:输入:grid=[[1......
  • LeetCode--Dota2 参议院(day 2)
     今天给大家带来LeetCode中的一道算法题:参议院问题,忘记具体内容的朋友可以观看下图: 根据题意,我们可以清楚的认识到获胜条件:那就是字符串中仅包含D或R。 我们先以RDRDD为例进行说明: 字符串中的第一个R行使权力,淘汰D阵营中的某一位,我们可以看见字符串中有三个D,那么该......
  • leetCode--爬楼梯(记录做题过程加深印象)
    首先最广泛的方法为递归,直接上代码:intclimbStairs(intn){if(n==1){return1;}if(n==2){return2;}if(flag[n])returnflag[n];returnflag[n]=climbStairs(n-1)+climbStair......
  • 【算法题】72. 编辑距离-力扣(LeetCode)
    【算法题】72.编辑距离-力扣(LeetCode)1.题目下方是力扣官方题目的地址72.编辑距离给你两个单词word1和word2,请返回将word1转换成word2所使用的最少操作数。你可以对一个单词进行如下三种操作:插入一个字符删除一个字符替换一个字符示例1:输入:word1="ho......
  • 875. 爱吃香蕉的珂珂(leetcode)
    https://leetcode.cn/problems/koko-eating-bananas/description/二段性:速度有得完和不吃完两个段关键点是编写check函数,比较繁杂classSolution{publicintminEatingSpeed(int[]piles,inth){intsum=0;intmax=0;for(inti=0;i<piles.......
  • Leetcode 154. 寻找旋转排序数组中的最小值 II
    1.题目基本信息1.1.题目描述已知一个长度为n的数组,预先按照升序排列,经由1到n次旋转后,得到输入数组。例如,原数组nums=[0,1,4,4,5,6,7]在变化后可能得到:若旋转4次,则可以得到[4,5,6,7,0,1,4]若旋转7次,则可以得到[0,1,4,4,5,6,7]注意,数组[a[0],a[1],a[2],......
  • 【LeetCode Hot 100】21. 合并两个有序链表
    题目描述最简单粗暴的想法是将两个链表的所有元素拿出来放在一个数组中,再将此数组排序,最后生成一个新链表并返回。由于给出的参数本身就是两个排好序的链表,可以进行一次遍历,就能保证元素仍然是有序的:每次比较当前指针指向的两个元素的大小,较小的拿出来作为当前元素并将指针向前移......