acwing1048、鸡蛋的硬度

发布时间 2023-09-09 22:57:53作者: Destidler

好久没做算法题了,偶然看到一道题练练手。(顺便复习一下markdown)
题目:
  用m个相同鸡蛋测n层楼,要测出鸡蛋硬度具体能抗几层楼高,问最少要测试几次(即丢几次鸡蛋)。
题目解析:
  是一道很简单的题目的延申?考虑一种较为简单的情况:100层楼,2个鸡蛋,此时假设让第一个鸡蛋在x楼落下(显然,1<=x<=n),则可能出现以下两种情况:
  1)鸡蛋摔碎,那么后续只需要在下面的x-1个楼层继续测试,则问题变成了x-1层楼,2-1=1个鸡蛋;
  2)鸡蛋未摔碎,那么后续只需要在上面的100-x个楼层继续测试,则问题变成了100-x层楼,2个鸡蛋;
  由于以上两种情况均可能发生,所以我们自然要取两个问题之解中的最大值啦。
  !不要忘记已经摔了一次了!
  于是这就非常顺理成章地变成了一个dp[1]问题!
然后考虑一下边界情况:
  ·如果只剩下0层楼,那显然不用再试了;
  ·如果只剩下0个鸡蛋,那显然也不用再试了;(中华文化博大精深)
  ·由于0个鸡蛋对应的测试次数是无穷大,无法推导出1个鸡蛋时的测试次数,因此对于鸡蛋个数的边界应该是1个鸡蛋的情况,此时显然只能从1楼一层层往上走,要丢n次;
  于是dp就完成啦!
代码如下:

#include<bits/stdc++.h>
using namespace std;

int main() {
    int hardness, num;
    int times[101][11];
    for (int i = 0; i <= 100; i++) {
        for (int j = 0; j <= 10; j++) {
            times[i][j] = 111111111;
        }
    }
    for (int i = 1; i <= 100; i++) {
        times[i][1] = i;
    }
    for (int j = 1; j <= 10; j++) {
        times[0][j] = 0;
    }
    for (int j = 1; j <= 10; j++) {
        for (int i = 1; i <= 100; i++) {
            for (int k = 1; k <= i; k++) {
                times[i][j] = min(times[i][j], max(times[k-1][j-1], times[i-k][j]) + 1);
            }
        }
    }
    while (cin >> hardness >> num) {
        cout << times[hardness][num] << endl;
    }
	return 0;
}

思维竟然有点混乱,确实需要复健啊!


  1. Dynamic Programming,动态规划 ↩︎