鸡蛋掉落(Egg Dropping)问题的变种——带成本限制的鸡蛋掉落
字数 5839 2025-12-11 15:31:40

鸡蛋掉落(Egg Dropping)问题的变种——带成本限制的鸡蛋掉落


题目描述

你手上有 m 枚鸡蛋,可以用于测试一栋从 1n 层的高楼。已知鸡蛋有一个特殊的属性:

  • 如果从某一层 f 及以下掉落,鸡蛋不会碎。
  • 如果从高于 f 的楼层掉落,鸡蛋会碎。
    我们需要找到这个“临界楼层” f(即鸡蛋刚好不会碎的最高楼层)。

在经典“鸡蛋掉落”问题中,目标是找到最坏情况下最小尝试次数
在这个变种中,每次尝试有成本

  • 如果鸡蛋没碎,消耗成本 a
  • 如果鸡蛋碎了,消耗成本 b(通常 b > a,因为碎蛋损失更大)。
  • 你有一个总成本预算 C

目标:在总成本不超过 C 的前提下,通过合理安排测试楼层,确保一定能找到临界楼层 f。求在预算内能确保找到 f最大楼层数 n


问题形式化

输入:

  • 鸡蛋数量 mm >= 1
  • 没碎成本 a,碎了成本 ba, b 为正整数)
  • 总成本预算 C(正整数)

输出:

  • 最大可确保找到临界楼层 f 的楼层数 n

解题思路

这是一个“最坏情况下成本最小化”问题的反向:给定成本限制,最大化可处理的楼层数。
我们需要先理解最坏情况下的最小成本函数,然后在其不超过 C 的条件下求最大的 n


步骤1:定义状态与函数

dp[e][c] 表示在拥有 e 个鸡蛋、可用总成本为 c 时,能确保找到临界楼层的最大楼层数
注意这里 “可用总成本” 是指最坏情况下的成本上限
我们要求的是最大的 n 使得 dp[m][C] >= n,而 dp[m][C] 可以直接递推得到。

状态转移
假设我们在某一层 k 进行测试:

  • 如果鸡蛋没碎,则临界楼层在 k 及以上,剩下 e 个鸡蛋,剩余成本为 c - a(因为没碎消耗 a),可探索的更高楼层数为 dp[e][c-a]
  • 如果鸡蛋碎了,则临界楼层在 k 以下,剩下 e-1 个鸡蛋,剩余成本为 c - b,可探索的更低楼层数为 dp[e-1][c-b]

最坏情况下,我们需要确保能覆盖这两种可能,因此在 k 层测试能覆盖的总楼层数为:

\[1 + dp[e-1][c-b] + dp[e][c-a] \]

其中 1 表示当前测试的楼层 k 自身。
为了最大化可覆盖的楼层数,我们选择最优的 k 使得这个和最大。但注意,dp 的定义已经隐含了我们可以选择任意 k 使得两部分都能覆盖,所以直接相加即可(类似于二分策略的思想)。

因此状态转移方程为:

\[dp[e][c] = dp[e-1][c-b] + dp[e][c-a] + 1 \]

前提是 c >= bc >= a 以保证成本足够。


步骤2:边界条件

  • 如果没有鸡蛋(e = 0),无法测试,能覆盖的楼层数为 0:dp[0][c] = 0
  • 如果总成本 c < a(连一次测试的最低成本都不够),则一次测试也做不了,dp[e][c] = 0
  • 如果总成本足够但鸡蛋数 e = 1,只能从低到高逐层测试(因为碎了就没蛋了),最坏情况下需要测到顶层,且每次测试消耗 a(直到最后一次可能碎,但最坏情况是到顶层都没碎)。
    实际上,对于 e=1,一次测试的成本是 ab,最坏情况下我们假设在顶层测试时鸡蛋碎了,但必须保证碎之前的所有楼层都已确认。
    更精确的推导:
    设用 e=1 蛋,成本 c,最多可测的楼层数 dp[1][c]
    如果我们在某层测试:
    • 没碎:剩下成本 c-a,可继续往上测 dp[1][c-a] 层。
    • 碎了:剩下 0 蛋,无法继续。
      为了确保找到临界楼层,我们必须保证碎了之后不需要再测(即已经确定楼下都是安全的),因此应该从低到高测试,且每次测试的楼层是已知安全楼层 + 1。
      实际上,e=1 时,可测的最大楼层数就是满足成本约束的最大测试次数:
      设最多可进行 t 次测试,每次测试成本在没碎时为 a,最后一次可能碎(成本 b)或没碎(成本 a)。
      最坏情况是测试到第 t 次时鸡蛋才碎(或一直没碎),此时总成本为 (t-1)*a + bt*a
      为了覆盖最坏情况,必须保证 (t-1)*a + b <= ct*a <= c 中取更严格的。
      b > a 时,最坏成本是 (t-1)*a + b,解出最大整数 t 满足 (t-1)*a + b <= c,则 dp[1][c] = t
      但更简单的办法是直接递推:

\[ dp[1][c] = 1 + dp[1][c-a] \quad \text{(如果 } c \ge a \text{)} \]

并且注意如果某次测试碎了,我们就不能继续,所以上面的递推假设每次测试都不碎,这实际上是最优策略(因为从低到高测,确保安全)。
但更通用的递推可直接用原始方程,但限制 e=1dp[0][c-b] = 0,所以:

\[ dp[1][c] = dp[0][c-b] + dp[1][c-a] + 1 \]

dp[0][c-b] = 0,所以:

\[ dp[1][c] = dp[1][c-a] + 1 \quad (\text{当 } c \ge a) \]

c < adp[1][c] = 0
如果 c 足够大,dp[1][c] 会超过 c/a,这是合理的,因为测试次数可以比 c/a 多一次(如果最后一次碎,成本是 b 但可能 b > a,所以需要更严格的限制)。
但为了精确,我们直接采用原始方程,其中 dp[0][x] = 0 对所有 x,这样递推会自动处理边界。


步骤3:递推顺序

我们需要按 e 从小到大、c 从小到大计算 dp[e][c]

  • 初始化 dp[0][c] = 0 对所有 c
  • e = 1m,对 c = 0C
    如果 c < adp[e][c] = 0(一次测试也做不了)。
    否则,如果 c < b 则不能做会碎的测试(即不能从可能碎的楼层测),但我们可以选择在足够低的楼层测确保不碎,但为了最大化覆盖,应允许碎的情况,所以如果 c < bdp[e][c] = dp[e][c-a] + 1(相当于只能做不碎的测试)。
    实际上,完整方程是:

\[ dp[e][c] = \max_{1 \le k \le n} \left(1 + dp[e-1][c-b] + dp[e][c-a]\right) \]

k 的选择被隐含了,因为 dp[e-1][c-b]dp[e][c-a] 已经是最优覆盖数,所以直接相加即可,不需要枚举 k
因此递推式为:

\[ dp[e][c] = dp[e-1][c-b] + dp[e][c-a] + 1 \]

c >= bc >= a,否则用边界条件。


步骤4:算法流程

  1. 初始化二维数组 dp[m+1][C+1] 为 0。
  2. e 从 1 到 m
    • c 从 1 到 C
      • 如果 c < adp[e][c] = dp[e][c-1](因为成本不够测试,继承之前的结果,但这里更准确是0,除非 e=1 有特殊情况)。更安全的做法是直接按公式计算,但要避免负索引。
        实现时,我们可以这样:

\[ \text{if } c \ge a: \quad up = dp[e][c-a] \text{ else } up = 0 \]

\[ \text{if } c \ge b: \quad down = dp[e-1][c-b] \text{ else } down = 0 \]

\[ dp[e][c] = up + down + 1 \]

 但这样会重复计算当前楼层,可能导致楼层数被高估。实际上,我们需要确保 `up` 和 `down` 对应的剩余成本足够做后续测试。  
 更严谨的方法是用“测试次数”思想,但这里采用标准动态规划解法:  
 设 `f(e, c)` 为最大可测楼层数,则:
 - 如果我们在第 `x` 层测试(1 <= x <= f(e,c)):  
   没碎:剩下 `e` 蛋,成本 `c-a`,可测 `f(e, c-a)` 层,且这些在 `x` 之上,所以总楼层可达 `x + f(e, c-a)`。  
   碎了:剩下 `e-1` 蛋,成本 `c-b`,可测 `f(e-1, c-b)` 层,在 `x` 之下。  
   为了确保一定能找到临界楼层,我们需要选择 `x` 使得:

\[ x = 1 + f(e-1, c-b) \]

   因为如果碎了,我们需要能覆盖下面的 `f(e-1, c-b)` 层,所以从第 `1 + f(e-1, c-b)` 层测试。  
   如果没碎,我们还能往上覆盖 `f(e, c-a)` 层。  
   因此总覆盖楼层数为:

\[ f(e, c) = f(e-1, c-b) + 1 + f(e, c-a) \]

   与前面一致。  
 所以递推式正确。
  1. 最终答案就是 dp[m][C],因为它表示在 m 个蛋、成本 C 时能保证确定临界楼层的最大楼层数。

步骤5:例子验证

例:m=2, a=1, b=2, C=6
我们计算 dp[e][c] 表:

  • 初始化 dp[0][c] = 0

  • e=1
    c=0: 0
    c=1: dp[1][1] = dp[0][-1]? 不可,用公式:c=1>=a=1, c<b=2, 所以 down=0, up=dp[1][0]=0, 则 dp[1][1]=0+0+1=1。
    c=2: c>=a, c>=b, up=dp[1][1]=1, down=dp[0][0]=0, dp=1+0+1=2。
    c=3: up=dp[1][2]=2, down=dp[0][1]=0, dp=2+0+1=3。
    实际上,e=1 时,dp[1][c] = floor((c - (b-a)?) 但按递推:
    c=4: up=dp[1][3]=3, down=dp[0][2]=0, dp=4。
    所以 e=1 时,dp[1][c] = c - (b-a)? 不对,检查:
    c=5: up=dp[1][4]=4, down=dp[0][3]=0, dp=5。
    所以 e=1 时,dp[1][c] = c - (b-a) 不成立,而是 dp[1][c] = c - (b-a) ?我们手算几个:
    c=6: up=dp[1][5]=5, down=dp[0][4]=0, dp=6。
    似乎 dp[1][c] = c ?验证:e=1 时,每次测试成本 a=1,最坏情况是到顶层才碎,成本为 (n-1)a + b = n-1+2 = n+1 <= c,所以 n <= c-1。
    但我们的递推得 n = c。矛盾。
    说明递推有误:递推假设每次测试后蛋都没碎,但实际最后一次可能碎,成本是 b 而不是 a。
    因此递推中,当 e=1 时,应该用不同的公式:
    e=1 时,设可测 n 层,最坏成本是 (n-1)
    a + b(如果第 n 层碎),必须 <= c。
    所以 n <= (c - b)/a + 1。
    因此 dp[1][c] = floor((c - b)/a) + 1 如果 c >= b,否则为 floor(c/a)(因为如果 c<b,不可能承受碎的成本,所以只能测到不碎的楼层,即 c/a 次测试,每次成本 a,但最后一次可能碎不起,所以安全楼层数 = floor(c/a))。
    我们修正递推:当 e=1 时直接计算,不用通用公式。

    重新计算例子:
    m=2, a=1, b=2, C=6。
    e=1:
    c=0:0, c=1: floor(1/1)=1, c=2: floor((2-2)/1)+1=1, c=3: floor((3-2)/1)+1=2, c=4: floor((4-2)/1)+1=3, c=5:3? 等一下,c=5: (5-2)/1+1=4, c=6:(6-2)/1+1=5。
    所以 dp[1][6]=5。
    e=2: 用通用公式 dp[e][c] = dp[e-1][c-b] + dp[e][c-a] + 1。
    c=0:0, c=1: c>=a, c<b, down=0, up=dp[2][0]=0, dp=1。
    c=2: up=dp[2][1]=1, down=dp[1][0]=0, dp=2。
    c=3: up=dp[2][2]=2, down=dp[1][1]=1, dp=2+1+1=4。
    c=4: up=dp[2][3]=4, down=dp[1][2]=1, dp=4+1+1=6。
    c=5: up=dp[2][4]=6, down=dp[1][3]=2, dp=6+2+1=9。
    c=6: up=dp[2][5]=9, down=dp[1][4]=3, dp=9+3+1=13。
    所以最终 dp[2][6]=13。
    即 2 个蛋,成本预算 6,可确保测的最大楼层数为 13。


步骤6:复杂度

  • 时间复杂度:O(m * C)
  • 空间复杂度:O(m * C),可优化为 O(C) 因为递推只用到上一行和当前行的前面状态。

总结

这个变种将鸡蛋掉落问题的“最少次数”目标转化为“给定成本下的最大楼层”,通过动态规划计算 dp[e][c],其中递推式结合了最坏情况下的成本分配。关键点是正确处理 e=1 的边界情况,以及理解通用递推式的含义:每次测试将问题分成楼下和楼上两部分,分别用剩余资源解决。

鸡蛋掉落(Egg Dropping)问题的变种——带成本限制的鸡蛋掉落 题目描述 你手上有 m 枚鸡蛋,可以用于测试一栋从 1 到 n 层的高楼。已知鸡蛋有一个特殊的属性: 如果从某一层 f 及以下掉落,鸡蛋不会碎。 如果从高于 f 的楼层掉落,鸡蛋会碎。 我们需要找到这个“临界楼层” f (即鸡蛋刚好不会碎的最高楼层)。 在经典“鸡蛋掉落”问题中,目标是找到 最坏情况下 的 最小尝试次数 。 在这个变种中,每次尝试有 成本 : 如果鸡蛋没碎,消耗成本 a 。 如果鸡蛋碎了,消耗成本 b (通常 b > a ,因为碎蛋损失更大)。 你有一个总成本预算 C 。 目标 :在总成本不超过 C 的前提下,通过合理安排测试楼层,确保一定能找到临界楼层 f 。求在预算内能确保找到 f 的 最大楼层数 n 。 问题形式化 输入: 鸡蛋数量 m ( m >= 1 ) 没碎成本 a ,碎了成本 b ( a, b 为正整数) 总成本预算 C (正整数) 输出: 最大可确保找到临界楼层 f 的楼层数 n 解题思路 这是一个“最坏情况下成本最小化”问题的反向:给定成本限制,最大化可处理的楼层数。 我们需要先理解 最坏情况下的最小成本函数 ,然后在其不超过 C 的条件下求最大的 n 。 步骤1:定义状态与函数 设 dp[e][c] 表示在拥有 e 个鸡蛋、可用总成本为 c 时,能确保找到临界楼层的 最大楼层数 。 注意这里 “可用总成本” 是指 最坏情况下的成本上限 。 我们要求的是最大的 n 使得 dp[m][C] >= n ,而 dp[m][C] 可以直接递推得到。 状态转移 : 假设我们在某一层 k 进行测试: 如果鸡蛋没碎,则临界楼层在 k 及以上,剩下 e 个鸡蛋,剩余成本为 c - a (因为没碎消耗 a ),可探索的更高楼层数为 dp[e][c-a] 。 如果鸡蛋碎了,则临界楼层在 k 以下,剩下 e-1 个鸡蛋,剩余成本为 c - b ,可探索的更低楼层数为 dp[e-1][c-b] 。 最坏情况下,我们需要确保能覆盖这两种可能,因此在 k 层测试能覆盖的总楼层数为: \[ 1 + dp[ e-1][ c-b] + dp[ e][ c-a ] \] 其中 1 表示当前测试的楼层 k 自身。 为了最大化可覆盖的楼层数,我们选择最优的 k 使得这个和最大。但注意, dp 的定义已经隐含了我们可以选择任意 k 使得两部分都能覆盖,所以直接相加即可(类似于二分策略的思想)。 因此状态转移方程为: \[ dp[ e][ c] = dp[ e-1][ c-b] + dp[ e][ c-a ] + 1 \] 前提是 c >= b 且 c >= a 以保证成本足够。 步骤2:边界条件 如果没有鸡蛋( e = 0 ),无法测试,能覆盖的楼层数为 0: dp[0][c] = 0 。 如果总成本 c < a (连一次测试的最低成本都不够),则一次测试也做不了, dp[e][c] = 0 。 如果总成本足够但鸡蛋数 e = 1 ,只能从低到高逐层测试(因为碎了就没蛋了),最坏情况下需要测到顶层,且每次测试消耗 a (直到最后一次可能碎,但最坏情况是到顶层都没碎)。 实际上,对于 e=1 ,一次测试的成本是 a 或 b ,最坏情况下我们假设在顶层测试时鸡蛋碎了,但必须保证碎之前的所有楼层都已确认。 更精确的推导: 设用 e=1 蛋,成本 c ,最多可测的楼层数 dp[1][c] 。 如果我们在某层测试: 没碎:剩下成本 c-a ,可继续往上测 dp[1][c-a] 层。 碎了:剩下 0 蛋,无法继续。 为了确保找到临界楼层,我们必须保证碎了之后不需要再测(即已经确定楼下都是安全的),因此应该从低到高测试,且每次测试的楼层是已知安全楼层 + 1。 实际上, e=1 时,可测的最大楼层数就是满足成本约束的最大测试次数: 设最多可进行 t 次测试,每次测试成本在没碎时为 a ,最后一次可能碎(成本 b )或没碎(成本 a )。 最坏情况是测试到第 t 次时鸡蛋才碎(或一直没碎),此时总成本为 (t-1)*a + b 或 t*a 。 为了覆盖最坏情况,必须保证 (t-1)*a + b <= c 且 t*a <= c 中取更严格的。 当 b > a 时,最坏成本是 (t-1)*a + b ,解出最大整数 t 满足 (t-1)*a + b <= c ,则 dp[1][c] = t 。 但更简单的办法是直接递推: \[ dp[ 1][ c] = 1 + dp[ 1][ c-a ] \quad \text{(如果 } c \ge a \text{)} \] 并且注意如果某次测试碎了,我们就不能继续,所以上面的递推假设每次测试都不碎,这实际上是最优策略(因为从低到高测,确保安全)。 但更通用的递推可直接用原始方程,但限制 e=1 时 dp[0][c-b] = 0 ,所以: \[ dp[ 1][ c] = dp[ 0][ c-b] + dp[ 1][ c-a ] + 1 \] 而 dp[0][c-b] = 0 ,所以: \[ dp[ 1][ c] = dp[ 1][ c-a ] + 1 \quad (\text{当 } c \ge a) \] 当 c < a 时 dp[1][c] = 0 。 如果 c 足够大, dp[1][c] 会超过 c/a ,这是合理的,因为测试次数可以比 c/a 多一次(如果最后一次碎,成本是 b 但可能 b > a ,所以需要更严格的限制)。 但为了精确,我们直接采用原始方程,其中 dp[0][x] = 0 对所有 x ,这样递推会自动处理边界。 步骤3:递推顺序 我们需要按 e 从小到大、 c 从小到大计算 dp[e][c] 。 初始化 dp[0][c] = 0 对所有 c 。 对 e = 1 到 m ,对 c = 0 到 C : 如果 c < a 则 dp[e][c] = 0 (一次测试也做不了)。 否则,如果 c < b 则不能做会碎的测试(即不能从可能碎的楼层测),但我们可以选择在足够低的楼层测确保不碎,但为了最大化覆盖,应允许碎的情况,所以如果 c < b 则 dp[e][c] = dp[e][c-a] + 1 (相当于只能做不碎的测试)。 实际上,完整方程是: \[ dp[ e][ c] = \max_ {1 \le k \le n} \left(1 + dp[ e-1][ c-b] + dp[ e][ c-a ]\right) \] 但 k 的选择被隐含了,因为 dp[e-1][c-b] 和 dp[e][c-a] 已经是最优覆盖数,所以直接相加即可,不需要枚举 k 。 因此递推式为: \[ dp[ e][ c] = dp[ e-1][ c-b] + dp[ e][ c-a ] + 1 \] 当 c >= b 且 c >= a ,否则用边界条件。 步骤4:算法流程 初始化二维数组 dp[m+1][C+1] 为 0。 对 e 从 1 到 m : 对 c 从 1 到 C : 如果 c < a , dp[e][c] = dp[e][c-1] (因为成本不够测试,继承之前的结果,但这里更准确是0,除非 e=1 有特殊情况)。更安全的做法是直接按公式计算,但要避免负索引。 实现时,我们可以这样: \[ \text{if } c \ge a: \quad up = dp[ e][ c-a ] \text{ else } up = 0 \] \[ \text{if } c \ge b: \quad down = dp[ e-1][ c-b ] \text{ else } down = 0 \] \[ dp[ e][ c ] = up + down + 1 \] 但这样会重复计算当前楼层,可能导致楼层数被高估。实际上,我们需要确保 up 和 down 对应的剩余成本足够做后续测试。 更严谨的方法是用“测试次数”思想,但这里采用标准动态规划解法: 设 f(e, c) 为最大可测楼层数,则: 如果我们在第 x 层测试(1 <= x <= f(e,c)): 没碎:剩下 e 蛋,成本 c-a ,可测 f(e, c-a) 层,且这些在 x 之上,所以总楼层可达 x + f(e, c-a) 。 碎了:剩下 e-1 蛋,成本 c-b ,可测 f(e-1, c-b) 层,在 x 之下。 为了确保一定能找到临界楼层,我们需要选择 x 使得: \[ x = 1 + f(e-1, c-b) \] 因为如果碎了,我们需要能覆盖下面的 f(e-1, c-b) 层,所以从第 1 + f(e-1, c-b) 层测试。 如果没碎,我们还能往上覆盖 f(e, c-a) 层。 因此总覆盖楼层数为: \[ f(e, c) = f(e-1, c-b) + 1 + f(e, c-a) \] 与前面一致。 所以递推式正确。 最终答案就是 dp[m][C] ,因为它表示在 m 个蛋、成本 C 时能保证确定临界楼层的最大楼层数。 步骤5:例子验证 例: m=2, a=1, b=2, C=6 。 我们计算 dp[e][c] 表: 初始化 dp[0][c] = 0 。 e=1 : c=0 : 0 c=1 : dp[1][1] = dp[0][-1]? 不可,用公式:c=1>=a=1, c<b=2, 所以 down=0, up=dp[ 1][ 0]=0, 则 dp[ 1][ 1 ]=0+0+1=1。 c=2 : c>=a, c>=b, up=dp[ 1][ 1]=1, down=dp[ 0][ 0 ]=0, dp=1+0+1=2。 c=3 : up=dp[ 1][ 2]=2, down=dp[ 0][ 1 ]=0, dp=2+0+1=3。 实际上,e=1 时,dp[ 1][ c ] = floor((c - (b-a)?) 但按递推: c=4: up=dp[ 1][ 3]=3, down=dp[ 0][ 2 ]=0, dp=4。 所以 e=1 时,dp[ 1][ c ] = c - (b-a)? 不对,检查: c=5: up=dp[ 1][ 4]=4, down=dp[ 0][ 3 ]=0, dp=5。 所以 e=1 时,dp[ 1][ c] = c - (b-a) 不成立,而是 dp[ 1][ c ] = c - (b-a) ?我们手算几个: c=6: up=dp[ 1][ 5]=5, down=dp[ 0][ 4 ]=0, dp=6。 似乎 dp[ 1][ c] = c ?验证:e=1 时,每次测试成本 a=1,最坏情况是到顶层才碎,成本为 (n-1) a + b = n-1+2 = n+1 <= c,所以 n <= c-1。 但我们的递推得 n = c。矛盾。 说明递推有误:递推假设每次测试后蛋都没碎,但实际最后一次可能碎,成本是 b 而不是 a。 因此递推中,当 e=1 时,应该用不同的公式: e=1 时,设可测 n 层,最坏成本是 (n-1) a + b(如果第 n 层碎),必须 <= c。 所以 n <= (c - b)/a + 1。 因此 dp[ 1][ c] = floor((c - b)/a) + 1 如果 c >= b,否则为 floor(c/a)(因为如果 c <b,不可能承受碎的成本,所以只能测到不碎的楼层,即 c/a 次测试,每次成本 a,但最后一次可能碎不起,所以安全楼层数 = floor(c/a))。 我们修正递推:当 e=1 时直接计算,不用通用公式。 重新计算例子: m=2, a=1, b=2, C=6。 e=1: c=0:0, c=1: floor(1/1)=1, c=2: floor((2-2)/1)+1=1, c=3: floor((3-2)/1)+1=2, c=4: floor((4-2)/1)+1=3, c=5:3? 等一下,c=5: (5-2)/1+1=4, c=6:(6-2)/1+1=5。 所以 dp[ 1][ 6 ]=5。 e=2: 用通用公式 dp[ e][ c] = dp[ e-1][ c-b] + dp[ e][ c-a ] + 1。 c=0:0, c=1: c>=a, c<b, down=0, up=dp[ 2][ 0 ]=0, dp=1。 c=2: up=dp[ 2][ 1]=1, down=dp[ 1][ 0 ]=0, dp=2。 c=3: up=dp[ 2][ 2]=2, down=dp[ 1][ 1 ]=1, dp=2+1+1=4。 c=4: up=dp[ 2][ 3]=4, down=dp[ 1][ 2 ]=1, dp=4+1+1=6。 c=5: up=dp[ 2][ 4]=6, down=dp[ 1][ 3 ]=2, dp=6+2+1=9。 c=6: up=dp[ 2][ 5]=9, down=dp[ 1][ 4 ]=3, dp=9+3+1=13。 所以最终 dp[ 2][ 6 ]=13。 即 2 个蛋,成本预算 6,可确保测的最大楼层数为 13。 步骤6:复杂度 时间复杂度:O(m * C) 空间复杂度:O(m * C),可优化为 O(C) 因为递推只用到上一行和当前行的前面状态。 总结 这个变种将鸡蛋掉落问题的“最少次数”目标转化为“给定成本下的最大楼层”,通过动态规划计算 dp[e][c] ,其中递推式结合了最坏情况下的成本分配。关键点是正确处理 e=1 的边界情况,以及理解通用递推式的含义:每次测试将问题分成楼下和楼上两部分,分别用剩余资源解决。