题目:

  1. 你将获得 K 个鸡蛋,并可以使用一栋从 1 N 共有 N 层楼的建筑。
  2. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。
  3. 你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。
  4. 每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。
  5. 你的目标是确切地知道 F 的值是多少。
  6. 无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?
  7. 示例 1
  8. 输入:K = 1, N = 2
  9. 输出:2
  10. 解释:
  11. 鸡蛋从 1 楼掉落。如果它碎了,我们肯定知道 F = 0
  12. 否则,鸡蛋从 2 楼掉落。如果它碎了,我们肯定知道 F = 1
  13. 如果它没碎,那么我们肯定知道 F = 2
  14. 因此,在最坏的情况下我们需要移动 2 次以确定 F 是多少。
  15. 来源:力扣(LeetCode
  16. 链接:https://leetcode-cn.com/problems/super-egg-drop
  17. 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

答案:

时间:

正无穷

  1. class Solution:
  2. def superEggDrop(self, K: int, N: int) -> int:
  3. @functools.lru_cache(None)
  4. def dfs(k, n):
  5. if n == 0: return 0
  6. if k == 1: return n
  7. lo, hi = 1, n
  8. while lo+1 < hi: # 离散函数这时已经找到两个最低点了
  9. mid = (lo + hi) // 2
  10. broken = dfs(k-1, mid-1)
  11. not_broken = dfs(k, n-mid)
  12. if not_broken< broken:
  13. # broken好,鸡蛋抗摔,所以要往上移动x
  14. hi= mid
  15. elif not_broken> broken:
  16. lo= mid
  17. else:
  18. lo=hi=mid
  19. ans = 1 + min(max(dfs(k-1, mid - 1), dfs(k, n - mid)) for mid in (lo, hi))
  20. #in : x为low时计算一个值,为high时计算一个值,比较二者 |||注意不是in range()
  21. return ans
  22. return dfs(K, N)

要点:

1. dp 定义

k鸡蛋,n层楼,从x层丢下去
887. 鸡蛋掉落 - 图1
第一项是摔碎了,第二项是没摔碎
max是表示两者的最坏情况,min表示我选择出了最好的x。

2. 这个二分查找太难了……

真是10个二分9个错

答案:

  1. class Solution:
  2. def superEggDrop(self, K: int, N: int) -> int:
  3. if N==1:return 1
  4. if K==1:return N
  5. dp=[[0]*(K+1) for _ in range(N+1)]
  6. for i in range(1,N+1):
  7. for j in range(1,K+1):
  8. dp[i][j]= 1+dp[i-1][j-1]+dp[i-1][j]
  9. if dp[i][j]>=N:
  10. return i

要逆向思维,不过我一开始就是这个方向,但是打死我也想不出来是这么转移的。

其他:

代码报错:无