leetcode每日一题(打卡篇)

文章目录

4-11.鸡蛋掉落

思路:
这道题主要分两部分,一个是写出转移方程,另一个是优化算法。

  • 只有一个鸡蛋的时候,只能从1层开始扔,一层一层扔才能保证得到F楼层。(如果从其他楼层开始扔, 如果碎了,那么无法确定F是在当前楼层还是低楼层。)
  • 有多个鸡蛋的时候,第一个鸡蛋可以从任意楼层扔(j楼);
    1)如果碎了,那么F楼层在比当前低的楼层中,鸡蛋个数减一,移动次数为当有k-1个鸡蛋时,j-1楼最小的移动次数+1。
    2)如果没碎,那么F楼层在比当前高的楼层中,鸡蛋个数不变,移动次数为当前k个鸡蛋,N-j楼最小的移动次数+1
  • 第一个鸡蛋可在某个楼层扔时,使得整体移动次数最小,找到它!

举个例子:
比如K=2,N=9
这个留着,以后画图方便时再写吧…
简单解释下代码:
lis[i][j]表示,i个鸡蛋j层楼所需最小移动次数。
二分法来找到第一个鸡蛋扔的最佳位置,如果用for循环会超时。
m代表第一个鸡蛋在哪个楼层扔,
低楼层所需的最小次数为lis[i-1][m-1];
高楼层所需的最小次数为lis[i][j-m];

当两者尽可能接近的时候,楼层最优。
两者有一个趋势,低楼层所需的最小次数是不断增加的,即一个递增序列,找到使得低楼层所需最小次数最大且小于等于高楼层所需最小次数即可。
算法的时间复杂度是:O(KNlogN)

在这里插入代码class Solution(object):
    def superEggDrop(self, K, N):
        """
        :type K: int
        :type N: int
        :rtype: int
        """
        lis = [[0 for i in range(N+1)] for j in range(K)]
        for i in range(K):
            for j in range(1,N+1):
                if i == 0:
                    lis[i][j] = j
                elif j == 1:
                    lis[i][j] = 1
                else:
                    #找分割点
                    lf = 1
                    rg = j
                    m = (lf + rg)>>1
                    while lf < rg:
                        if lis[i-1][m-1] < lis[i][j-m]:
                            lf = m+1
                        elif lis[i-1][m-1] > lis[i][j-m]:
                            rg = m
                        else:
                            break
                        m = (lf+rg)>>1
                    lis[i][j] = lis[i-1][m-1] + 1
        # print lis
        return lis[-1][-1]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值