高楼扔鸡蛋问题(鹰蛋问题) POJ-3783
这是一道经典的DP模板题。
https://vjudge.net/problem/POJ-3783#author=Herlo
一开始也是不知道咋写,尝试找了很多博客,感觉有点领悟之后写下自己的理解。
题意就是:
对于一种蛋,如果它在第m层楼摔不碎,但是在第m+1层摔碎了,那么它的硬度就是m。
有若干层楼,你有若干个一样的蛋,你每一次尝试的结果都会是最坏的情况,问你在这种运气最差的情况下至少丢几次蛋才能知道它的硬度。
A. 如果蛋的数量是0,那根本都尝试不了,只能试0次
B. 如果你只有一个蛋,那你不敢随便丢吧?如果现在有100层你随便挑第50层一丢,它碎了,那你怎么确定它的硬度是多少?那么就只能从一楼开始一层一层往上试,直到它摔碎了,那么我们也确定了蛋的硬度。
C. 如果你有两个蛋,那么你可以先尝试着在第k层丢一个蛋
- 如果蛋碎了,那么你手中只剩下一颗蛋能试了,这个时候你也知道,从第k+1层往上的层你也不用再考虑了,接下来剩下的一个蛋就在第1到第k-1层做尝试就好了。
- 如果它没碎,那么你手中还剩下两颗完好的蛋,并且,这个时候k层下面的1到k-1层,你都不用考虑在这些层丢蛋了,肯定不会碎,那就只需要考虑从第k+1层开始到顶层,你该怎样去尝试,来测出这个蛋的硬度了。
看到上面两种情况,第一种情况,蛋的数量减小成为1了,并且待测的楼的层数也减少了,本质上变成了一个原问题的子问题,那么这个时候,我们可以看到当蛋只有一个,并且待测的楼层是k-1层时,这个答案肯定就是k-1啦,(只有一个蛋嘛)
第二种情况,蛋还是2个,不过待测的楼层数也减少了,这个也是原问题的子问题,我们可以看到因为扔一个蛋只可能出现碎与不碎两种情况,并且需要尝试的次数是由前面我们说到的这两种子问题的情况再加上1次得来的,那么因为题目说是最坏的情况,所以这两个子问题,自然是哪个次数大,就选哪个来加上1来推出规模更大的子问题。
D. 如果你有不止两个蛋,情况也是和上面说的一样,需要由子问题来推导得到,dp的本质也就是从子问题的最优解得到更大规模的子问题的最优解嘛。
我们的dp数组有两个维度,第一个是蛋的数量,第二个是待测的楼层数,
那么少不了两重循环来填表咯。
外层i就是蛋的数量,内层j就是待测的楼层数
E. 不过,这里还有一个问题,就是你在解决某一个子问题,假设是填dp【i】【j】这个格子的时候,如上文所说,你首先要在第k层先试扔一个吧?但这个k你怎么确定呢?这个时候,因为题目要求的是最小的扔的次数,所以最暴力的方法当然就是对于所有可能的k都遍历一遍啦,然后取一个最小的值来填我们的dp【i】【j】咯。
所以既然这样,我们先将所有dp都设置为INF(无限大),因为要取一个最小值来填dp【i】【j】嘛,然后,上文A、B中的情况是不需要推出来的,是直接可以得到的结果,也就是我们的初始化条件。
然后就是我们的三重循环填dp啦,
递推式在代码中,结合上述文字仔细品味一下,应该不太难理解。
此外,对于上文E这句话中的k值,好像还有更加优化的方法去做?(比如二分吗?)留待以后更新
题解代码
#include<iostream>
#include<cstdio>
using namespace std;
const int INF = 0x3f3f3f3f;
int cnt = 0,N;
const int maxn = 10005;
int T,id,B,M;
int dp[55][1005];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&id,&B,&M);
for(int i=1;i<=B;i++){
for(int j=1;j<=M;j++)
dp[i][j] = INF;
for(int i=0;i<=B;i++) dp[i][1] = 1, dp[i][0] = 0;
for(int i=0;i<=M;i++) dp[1][i] = i;
for(int i=2;i<=B;i++){
for(int j=2;j<=M;j++){
for(int k=1;k<=j;k++)
dp[i][j] = min(dp[i][j],1+max(dp[i-1][k-1],dp[i][j-k]));
}
}
cout<<id<<" "<<dp[B][M]<<endl;
}
return 0;
}
高楼扔鸡蛋问题(鹰蛋问题) POJ-3783的更多相关文章
- Google面试题-高楼扔鸡蛋问题
本文由 @lonelyrains 出品.转载请注明出处. 文章链接: http://blog.csdn.net/lonelyrains/article/details/46428569 高楼扔鸡蛋问 ...
- zstu 4214 高楼扔鸡蛋(google 面试题)dp
input T 1<=T<=10000 n m 1<=n<=2000000007 1<=m<=32 output m个鸡蛋从1到n哪一楼x扔下去刚好没碎,而再x+1 ...
- Chernobyl’ Eagle on a Roof(鹰蛋坚固度)
链接 Chernobyl’ Eagle on a Roof 题意 引用论文题意:有一堆共 M 个鹰蛋,一位教授想研究这些鹰蛋的坚硬度 E.他是通过不断从一幢 N 层的楼上向下扔鹰蛋来确定 E 的.当鹰 ...
- What number should I guess next ?——由《鹰蛋》一题引发的思考
What number should I guess next ? 这篇文章的灵感来源于最近技术部的团建与著名的DP优化<鹰蛋>.记得在一个月前,查到鹰蛋的题解前,我在与同学讨论时,一直试 ...
- [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. I ...
- poj 3783 Balls 动态规划 100层楼投鸡蛋问题
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098409.html 题目链接:poj 3783 Balls 动态规划 100层楼投鸡蛋问题 ...
- 扔鸡蛋问题具体解释(Egg Dropping Puzzle)
经典的动态规划问题,题设是这种: 假设你有2颗鸡蛋,和一栋36层高的楼,如今你想知道在哪一层楼之下,鸡蛋不会被摔碎,应该怎样用最少的測试次数对于不论什么答案楼层都可以使问题得到解决. 假设你从某一层楼 ...
- 扔鸡蛋问题详解(Egg Dropping Puzzle)
http://blog.csdn.net/joylnwang/article/details/6769160 经典的动态规划问题,题设是这样的:如果你有2颗鸡蛋,和一栋36层高的楼,现在你想知道在哪一 ...
- Balls(扔鸡蛋问题)
4554 BallsThe classic Two Glass Balls brain-teaser is often posed as:“Given two identical glass sphe ...
随机推荐
- 23、nginx动态添加nginx_upstream_check_module健康检查模块
nginx_upstream_check_module模块地址:https://github.com/yaoweibin/nginx_upstream_check_module 23.1.说明: 1. ...
- 关于asp.net中Repeater控件的一些应用
在Asp.net中,我是比较喜欢用Repeater这个控件,刚刚遇到的一个问题,怎么实现单击 <asp:LinkButton>,通过后台的单击事件获取同一行数据中的其他数据(对象). 1, ...
- 使用.net6 WebApplication打造最小API
.net6在preview4时给我们带来了一个新的API:WebApplication,通过这个API我们可以打造更小的轻量级API服务.今天我们来尝试一下如何使用WebApplication设计一个 ...
- CentOS-自定义SFTP用户及目录
ftp功能说明:通过SSH启动CentOS的sftp功能 创建用户组及用户(sftp可变) $ groupadd sftp $ useradd -g sftp -s /sbin/nologin -d ...
- edraw max for mac 安装
1.下载网址:https://xclient.info/s/edraw-max.html#versions 2.安装断网安装,直接打开 .dmg文件安装 3.按照阅读文件中的第二步,将opt.cell ...
- windows下命令
shutdown -s -t 0 关机 shutdown -r -t 0 重启 mstsc 远程桌面 notepad 记事本 regedit 注册表 calc 计算器 start applicatio ...
- iOS基于AVFoundation实现朗读文字
iOS基于AVFoundation实现朗读文字 1.心理建设 众所周知AVFoundation的朗读是个智障语气,所以想不花钱就只能忍着. 2.speechManager @import AVFoun ...
- 初步了解Unix系统的I/O模式
I/O模式 对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间. 当一个read操作发生时,它会经历两个阶段: 等待数据 ...
- Java | 一个".java"源文件中是否可以包括多个类(不包括内部类)
第一种情况:(有public) 定义一个java源文件(Hello.java),里面只有一个类: public class Hello { public static void main(string ...
- 深入理解C++11 阅读笔记
二 保证稳定性和兼容性保持与C99兼容 预定义宏 C99语言标准增加的一些预定义宏,C++11同样增加了对这些宏的支持 __func__预定义标识符 功能是返回所在函数的名字,在C++11中,标准甚至 ...