大楼扔鸡蛋问题(动态规划)

题目链接:poj 3783

题意分析:

经典题,小白书上的一道例题,4+2出了这道原题,我愣是以为是数学题,最后也没做出来。题意是这样的,给你N个鸡蛋(硬度一样),让你测鸡蛋的硬度,测量的方法就是从某栋M层的楼的某一层X上把鸡蛋扔下来,如果鸡蛋碎了,代表他的强度小于X;如果没碎,则强度大于等于X。我们要做的就是不断的从楼上把鸡蛋扔下来,直到找到某一层楼X,从这一层楼扔下来鸡蛋不碎掉,从X+1层扔下来鸡蛋碎掉,那么鸡蛋的强度就是X。如果在M层扔下来鸡蛋也不碎掉,那么鸡蛋的强度为M。问题是,用N个鸡蛋最多需要几步可以把硬度测出来(鸡蛋碎掉就不能用了,而且必须测出来!)。

解题思路:

一开始看懂题意之后,我马上就想到了二分法,但是仔细一想并不对,如果鸡蛋的数量足够的话,二分法绝对是最快的,但是如果鸡蛋不够,就不太一样了。如果第一次扔就碎了一个鸡蛋,那么剩下的鸡蛋就只能从下往上测试,这样2个鸡蛋、100层楼的情况最多可能需要51步,然而测试样例告诉我们,只要14步,当时想了足足有半个钟才想到他可以用{ 14,13,12 …… }这样的步长进行测试,这样最多的测试数都是14次,这样的原则确确实实可以解决2个鸡蛋的问题,但是3个鸡蛋就跪了,于是有了动态规划算法。

动态规划算法:

状态:

dp[i][j]表示N=i,M=j时,最多需要多少次测试。

状态转移方程:

如果我们一开始是在k层进行测试的,那么如果鸡蛋破碎了,我们的查找范围就变成k层一下的k-1层,当然此时鸡蛋数减少了,所以最终的步数应该为dp[i-1][k-1]+1;另外一种情况是鸡蛋没有碎的情况,我们要找的范围变成了k层以上的,所以最终需要dp[i][j-k]+1步。我们的目标就是要找到一个k,使得最坏情况下测试数最少,所以我们需要枚举k。代码如下:

    for(int i=2;i<=MAXN;i++)
    {
        for(int j=2;j<=MAXM;j++)
        {
            for(int k=1;k<j;k++)
            {
                dp[i][j]=min(dp[i][j],max(dp[i-1][k-1]+1,dp[i][j-k]+1));
            }
        }
    }

初始状态:

N=1时,测试数为M;M=1,测试数为1;M=0,测试数为0;

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define MAXN 55
#define MAXM 1005

using namespace std;

int n,m,dp[55][1005];

int main()
{
    int T,t;
    scanf("%d",&T);

    memset(dp,INF,sizeof(dp));
    for(int i=1;i<=MAXM;i++)
        dp[1][i]=i;
    for(int i=1;i<=MAXN;i++)
        dp[i][1]=1,dp[i][0]=0;

    for(int i=2;i<=MAXN;i++)
    {
        for(int j=2;j<=MAXM;j++)
        {
            for(int k=1;k<j;k++)
            {
                dp[i][j]=min(dp[i][j],max(dp[i-1][k-1]+1,dp[i][j-k]+1));
            }
        }
    }   

    while(T--)
    {
        scanf("%d %d %d",&t,&n,&m);
        printf("%d %d\n",t,dp[n][m]);
    }

    return 0;
}

总结:

其实如果知道是用动态规划做的话,状态什么的还是挺好想的,但是关键是想不到啊~~经验不足真可怕,不过被时间复杂度吓到也是一部分原因,居然没想到离线。

1、多坐点题积累经验吧;

2、不要被复杂度吓到;

3、事实证明,智商很重要TAT

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 07:41:43

大楼扔鸡蛋问题(动态规划)的相关文章

POJ 3783 Balls(扔鸡蛋问题——DP动态规划)

传送门 Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 892 Accepted: 588 Description The classic Two Glass Balls brain-teaser is often posed as: "Given two identical glass spheres, you would like to determine the lowest floor in a 100-s

扔鸡蛋

Description Jzj要来做一个经典的实验:测试鸡蛋壳的坚硬程度. Jzj正好处于N层高的摩天大楼中,所以通过从某一楼层向下扔鸡蛋来测试鸡蛋壳的坚硬程度. Jzj有M个鸡蛋,所有的鸡蛋硬度都一样.如果鸡蛋从第L层摔下去没有碎,而在L+1层摔碎了,那么称鸡蛋的硬度是L.嗯,反正jzj不喜欢吃鸡蛋,所以不用担心浪费的问题.大楼共有N层高,如果在N层还没有摔碎,就认为硬度是N:如果在第1层就碎了,硬度为0. 虽然jzj不喜欢吃鸡蛋,但是jzj的好朋友yk特别喜欢吃鸡蛋.为了帮好朋友保护可怜的小

扔鸡蛋问题详解(Egg Dropping Puzzle)

http://blog.csdn.net/joylnwang/article/details/6769160 经典的动态规划问题,题设是这样的:如果你有2颗鸡蛋,和一栋36层高的楼,现在你想知道在哪一层楼之下,鸡蛋不会被摔碎,应该如何用最少的测试次数对于任何答案楼层都能够使问题得到解决. 如果你从某一层楼扔下鸡蛋,它没有碎,则这个鸡蛋你可以继续用 如果这个鸡蛋摔碎了,则你可以用来测试的鸡蛋减少一个 所有鸡蛋的质量相同(都会在同一楼层以上摔碎) 对于一个鸡蛋,如果其在楼层i扔下的时候摔碎了,对于任

扔鸡蛋问题具体解释(Egg Dropping Puzzle)

经典的动态规划问题,题设是这种: 假设你有2颗鸡蛋,和一栋36层高的楼,如今你想知道在哪一层楼之下,鸡蛋不会被摔碎,应该怎样用最少的測试次数对于不论什么答案楼层都可以使问题得到解决. 假设你从某一层楼扔下鸡蛋,它没有碎,则这个鸡蛋你能够继续用 假设这个鸡蛋摔碎了,则你能够用来測试的鸡蛋降低一个 全部鸡蛋的质量同样(都会在同一楼层以上摔碎) 对于一个鸡蛋,假设其在楼层i扔下的时候摔碎了,对于不论什么不小于i的楼层,这个鸡蛋都会被摔碎 假设在楼层i扔下的时候没有摔碎,则对于不论什么不大于i的楼层,这

扔了一晚上的鸡蛋,找出来了第一次扔鸡蛋的最佳地点

http://blog.csdn.net/joylnwang/article/details/6769160 先给大家看看大神写的扔鸡蛋问题.所有的原理,DP实现都在,不赘述.大家好好学习,天天向上. 我想分享的是: 第一次扔地点的最佳地点的递归找法:(自己的测试都过了,希望大家都来查错:想按照大神的意思,找出所有的分界点,即找出扔各个鸡蛋的碎或没碎太困难啦,啥时候想到再分享给大家) 贴代码解释: #include<cstdio> #include<string> #include

[CareerCup] 6.5 Drop Eggs 扔鸡蛋问题

6.5 There is a building of 100 floors. If an egg drops from the Nth floor or above, it will break. If it's dropped from any floor below, it will not break. You're given two eggs. Find N, while minimizing the number of drops for the worst case 这道题说有10

Cracking the coding interview 智力题之-扔鸡蛋问题

问题: 解法: 这个问题算是一个智力题,没看过相关题目很难第一时间想出来.其中的"最差情况平衡"思路值得学习. 原文地址:https://www.cnblogs.com/J1ac/p/9248978.html

动态规划答疑篇

这篇文章就给你讲明白两个问题: 1.到底什么才叫「最优子结构」,和动态规划什么关系. 2.为什么动态规划遍历 dp 数组的方式五花八门,有的正着遍历,有的倒着遍历,有的斜着遍历. 一.最优子结构详解 「最优子结构」是某些问题的一种特定性质,并不是动态规划问题专有的.也就是说,很多问题其实都具有最优子结构,只是其中大部分不具有重叠子问题,所以我们不把它们归为动态规划系列问题而已. 我先举个很容易理解的例子:假设你们学校有 10 个班,你已经计算出了每个班的最高考试成绩.那么现在我要求你计算全校最高

鸡蛋的硬度

描述 最近XX公司举办了一个奇怪的比赛:鸡蛋硬度之王争霸赛.参赛者是来自世 界各地的母鸡,比赛的内容是看谁下的蛋最硬,更奇怪的是XX公司并不使用什么精密仪器来测量蛋的硬度,他们采用了一种最老土的办法--从高度扔鸡蛋--来 测试鸡蛋的硬度,如果一次母鸡下的蛋从高楼的第a层摔下来没摔破,但是从a+1层摔下来时摔破了,那么就说这只母鸡的鸡蛋的硬度是a.你当然可以找出各种 理由说明这种方法不科学,比如同一只母鸡下的蛋硬度可能不一样等等,但是这不影响XX公司的争霸赛,因为他们只是为了吸引大家的眼球,一个个