关于“高楼扔鸡蛋”这个问题

· · 算法·理论

今天上午,我们考了一张2022年的CSP-J入门级的初赛试卷,(结果我的成绩不怎么样题外话))。下午分析卷子的时候,有人说第二大题阅读程序的第二小题是“高楼扔鸡蛋”问题,题目给的程序用了 2 种方法解了“高楼扔鸡蛋”问题。

于是,老师用了大半个下午和我们讨论了“高楼扔鸡蛋”这个问题。

题目意思很简单:

有 n 层楼,m 个鸡蛋,在某一个楼层及其以下的楼层往地面扔鸡蛋,鸡蛋不会碎;但在这个楼层以上的楼层往地面扔鸡蛋,鸡蛋就会碎。让你求至少需要耗费多少个鸡蛋才能找到这个楼层。(当然啦,鸡蛋没碎便可以再次使用(还有一点,使用的鸡蛋个数不能超出 m 哦!))

上面已经说过啦~ 题目给出了两种解法,一种是用递归做,另一种嘛,自然是非递归啦,

我们先来讲讲递归的做法(代码与分析如下所示)

int f(int n, int m)
{
   if (m == 1) return n;
   if (n == 0) return 0;
   int ret = numeric_limits<int>::max();
   for (int i = 1; i <= n; i++)
    ret = min(ret, max(f(n - i, m), f(i - 1, m - 1)) + 1);               
   return ret;               
}

下面是第二种方法:

int g(int n, int m)
{
    for (int i = 1; i <= n; i++)
        h[i][1] = i;
    for (int j = 1; j <= m; j++)
        h[0][j] = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 2; j <= m; j++)
        {
            h[i][j] = numeric_limits<int>::max();
            for (int k = 1; k <= i; k++)
            h[i][j] = min(h[i][j] , max(h[i - k][j], h[k - 1][j - 1]) + 1);
        }
    }
    return h[n][m];
}

代码我就不多介绍了,

思路和上面的差不多,只是把递归改成循环了而已(自己理解吧~)

好了,下面我把完整代码放剪贴板里了

有兴趣的可以自己去看看

完整代码

老师还和我们讨论了当输入为“7 3”时,

ret = min(ret, max(f(n - i, m), f(i - 1, m - 1)) + 1);

一共运行了几次。

答案是448次。

原因我就不解释了,因为我马上要下课了,来不及解释了,拜拜~~

                2023.8.20