【经典算法题】鸡蛋的硬度
AcWing 1048. 鸡蛋的硬度
问题描述
-
问题链接:AcWing 1048. 鸡蛋的硬度
分析
- 本题使用
DP
解决,存在两种解法。
解法一
-
考虑初始化:
f[i][1]=i, f[1][j]=1
。 -
时间复杂度: O ( n 2 × m ) O(n ^ 2 \times m) O(n2×m) 。
解法二
-
可以反着想,现在总高度是
f[i - 1][j - 1] + f[i - 1][j] + 1
,然后在中间扔一次鸡蛋,如果没碎,那就递归到上半部分的情况继续操作,如果碎了,那就递归到下半部分的情况继续操作。这样不管答案在上半部分还是下半部分,都可以测试出来。 -
这里初始化:
f[i][0]=0, f[0][j]=0
。 -
时间复杂度: O ( n × m ) O(n \times m) O(n×m) 。
代码
- C++
// 解法一
#include <iostream>
using namespace std;
const int N = 110, M = 11;
int n, m;
int f[N][M];
int main() {
while (cin >> n >> m) {
for (int i = 1; i <= n; i++) f[i][1] = i; // 一个鸡蛋, i层楼
for (int i = 1; i <= m; i++) f[1][i] = 1; // i个鸡蛋, 一层楼
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++) {
f[i][j] = f[i][j - 1];
for (int k = 1; k <= i; k++)
f[i][j] = min(f[i][j], max(f[k - 1][j - 1], f[i - k][j]) + 1);
}
cout << f[n][m] << endl;
}
return 0;
}
// 解法二
#include <cstdio>
const int N = 110, M = 11;
int n, m;
int f[N][M];
int main() {
while (~scanf("%d%d", &n, &m)) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
f[i][j] = f[i - 1][j - 1] + f[i - 1][j] + 1;
if (f[i][m] >= n) {
printf("%d\n", i);
break;
}
}
}
return 0;
}