扔鸡蛋问题
Jun 20, 2021 • 🍻 04min 05s read
🔖 quiz动态规划
问题描述
¶有
算法一
¶将
上式的含义是,枚举区间长度为
若鸡蛋碎了,则还有
个鸡蛋可以使用,并只需要需要在区间长度为 的楼层里找到答案若鸡蛋没碎,则还有
个鸡蛋可以使用,并只需要在区间长度为 的楼层里找到答案
不难发现,如果直接暴力枚举,复杂度将高达
注意到
algorithm1.ts
1234567891011121314151617181920212223242526const MAX_K = 100 + 2const MAX_N = 10000 + 2const dp: number[][] = new Array(MAX_K)
function preprocess(): void { for (let k = 0; k < MAX_K; ++k) { dp[k] = new Array(MAX_N) dp[k][0] = 0 }
for (let n = 1; n < MAX_N; ++n) { dp[1][n] = n }
for (let k = 2; k < MAX_K; ++k) { const f: number[] = dp[k - 1] const h: number[] = dp[k] for (let n = 1; n < MAX_N; ++n) { const answer = lowerBound(f[1], f[n], candidateAnswer => { const x = lowerBound(1, n, y => f[y] <= candidateAnswer) return x <= 1 || h[n - x] > candidateAnswer }) h[n] = Math.min(f[n], answer + 1) } }}
算法二
¶记
如果鸡蛋摔碎了,则必须要使用
个鸡蛋在 次里测出前 层里能使鸡蛋摔碎的最小楼层,则取 是最优的(否则,无法在条件限制内完成测试)。如果鸡蛋没摔碎,则相当于把第
层看作第一层继续测试,因此最多还能测出 层楼。
因此,状态转移方程为:
Related
¶- Super Egg Drop | leetcode
- 算法竞赛入门经典(第2版) P292 装满水的气球 -- 刘汝佳