鸡蛋掉落----经典dp(动态规划)
题目:
给你
n
个鸡蛋,和一栋从1
到 m 共有m
层楼的建筑。你需要测试鸡蛋的耐摔度 也就是鸡蛋从第几层扔下去恰好会碎
如果鸡蛋的耐摔度是 F 那么任何从高于
F
的楼层落下的鸡蛋都会碎,从F
楼层或比它低的楼层落下的鸡蛋都不会破。你每次测试可以拿一个鸡蛋,把它从任意高度的楼层 扔下(没摔碎的话 还可以继续使用)
你的目标是测试出
F
的值是多少。要求在最坏的情况下 用尽量少的测试次数来找到鸡蛋的耐摔度
解题思路:
1、首先我们要理解题目意思,根据题意,我们很容易想到一种完成任务的笨方法,那就是拿一个鸡蛋,从一楼开始慢慢的往上层测试。这个方法可以只用一个鸡蛋就能找到耐摔度。但是需要的测试次数最大是N(如果N层也摔不碎 那你需要n次)
2、如何优化次数呢?可能很容易联想到二分查找,
我们假设有100层楼,给你两个鸡蛋。
用二分查找的话,我们首先在第50层楼扔,如果鸡蛋不碎的话,到第75层扔。如果50层碎了的话,那么你只剩下一个鸡蛋了,所以你不能浪了,只能使用第一个思路,从第一层开始慢慢往上找,这样才能保证你能找到临界楼层。
题目上说了,要我们考虑最坏情况下的最小次数,那么用二分查找的话,最坏情况就是如果临界层数在49层的话,我们要尝试50次。这个方法并不是最优秀的方法。
3、dp
先假设情况:2个鸡蛋,100层楼,求最坏的情况下,需要最少几次次测试才能找到鸡蛋的耐摔度
我们假设答案是x.(最坏需要x次)
然后我们首先在第x层扔鸡蛋 会有两种结果
1、碎了 若碎了 剩下的一个鸡蛋只能从1-(x-1)遍历尝试了
2、没碎 若没碎 那么第二次就在x+(x-1)楼层摔。
为什么是x+x-1楼层呢?
首先我们已经假设了通过x步我们就能得到答案,现在我们在x层已经用了一次了,那么就只剩下x-1步了。所以我们选择x+(x-1)层,如果碎了,我们就能通过x-2步,遍历x+1 ~ x+(x-1)-1的所有楼层。
依次类推。
如果在x+(x-1)楼碎了,那么同1,遍历x+1~x+(x-1)-1
如果没碎,那么同2,就在x+(x-1)+(x-2)层摔
.....................................
可以看到,每次我们增加的楼层都是前一次减1.所以我们还要保证的就是应该在增加的层数变成0之前到顶楼,
所以有: x+(x-1)+…+1≥100
等差数列 求和之后 可以化简为 x^2+x-200≥0 解出来 x是14
显然 14比我们二分的最坏情况50次要少 这就是正确答案。
那么 现在跳出我们假设的题目 推一下普适的方法
n个鸡蛋,m层楼
f[ n ][ m ]代表 最坏的情况下,找到鸡蛋的耐摔度需要的最小次数
状态转移方程为:f[n][m] = min { 1 + max ( f [ n-1 ][ k-1 ] , f [ n ][ m-k ] ) } k属于[1,m-1]
为什么是这样呢?
我们一层一层来看 先看内层
max ( f [ n-1 ][ k-1 ] , f [ n ][ m-k ] )
n个鸡蛋的时候,我们选择第k层往下摔
如果破了,那么手里只有n-1鸡蛋了,那么就需要测试f[n-1][k-1]楼层。
如果没破,那么手里还有n个鸡蛋,那么需要测试k+1 ~ m这些楼层。也就是f[n][m-k]。
而无论破没破 都算一次测试了 所以不管破没破 都要 + 1
而为什么取最大值呢?因为题目说了 要最坏情况 所以我们取这两者中步数多的
而k怎么选呢 再看总的式子
f[n][m] = min { 1 + max ( f [ n-1 ][ k-1 ] , f [ n ][ m-k ] ) } k属于[1,m-1]
k的选取范围是[1,m-1] 而我们目的是想测试次数最少 所以我们在这里面选一个会使结果最小的k值 所以外边枚举k,取min
至此 整个思路就完成了
初始话的时候 给整个二维数组都初始化为最坏情况 然后dp就好了
ps:补充一点 max ( f [ n-1 ][ k-1 ] , f [ n ][ m-k ] ) 有人认为没必要选最大 越高层越容易碎 所以直接选低层
这是不对的 要注意 确实越高层越容易碎 但是我们要求的是次数最小 跟碎不碎没关系 碎不碎都要算次数的 如果你想不碎 那直接从一层开始 一个鸡蛋就够了 所以 要明白我们要求的是什么
代码:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
const int INF=0x3f3f3f3f;
int a[105][10005];
int n,m,minn;
int main(){for(int i=1;i<=100;i++){//初始化for(int j=1;j<=10000;j++){a[i][j]=j;}}scanf("%d%d",&n,&m);//n个鸡蛋 m层楼for(int i=2;i<=n;i++){for(int j=2;j<=m;j++){for(int k=1;k<=j-1;k++){a[i][j]=min(a[i][j],1+max(a[i-1][k-1],a[i][j-k]));}}}printf("%d\n",a[n][m]);
}
参考文档:
https://blog.csdn.net/wolinxuebin/article/details/47057707
http://www.cnblogs.com/Matrix_Yao/p/4793823.html
鸡蛋掉落----经典dp(动态规划)相关推荐
- [Leedcode][JAVA][第887题][鸡蛋掉落][谷歌面试][动态规划]
[问题描述] [887. 鸡蛋掉落] 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑.每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去.你知道存在楼层 F ,满足 ...
- LeetCode 887. 鸡蛋掉落(DP,难、不懂)
1. 题目 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 <= F ...
- 动态规划经典题目_动态规划经典题目:鸡蛋掉落(附视频讲解)
题目: 思路: 先放上视频讲解 动态规划经典题目:鸡蛋掉落https://www.zhihu.com/video/1225199247848513536 纠正:视频里的状态转移方程漏写了一个+1,意思 ...
- 装鸡蛋的鞋子java代码_Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)...
887. 鸡蛋掉落 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 < ...
- dp 扔鸡蛋_使用动态编程(DP)的鸡蛋掉落问题
dp 扔鸡蛋 Problem statement: You are given N floor and K eggs. You have to minimize the number of times ...
- 【leetcode】鸡蛋掉落问题
在leetcode刷动态规划问题过程中,鸡蛋掉落问题是比较经典的,特别是笔试面试喜欢出的问题.腾讯,Vivo等大厂都出现过,在这里通过自己学习,以及借鉴大佬的思路,对这道题进行整理. 其它算法问题刷题 ...
- LeetCode887. 鸡蛋掉落
887. 鸡蛋掉落 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 < ...
- LeetCode887题:鸡蛋掉落——动态规划法与数学法
1. 问题介绍 关于临界楼层查找问题的最优查找策略,我已经在上一篇博客摔玻璃球(鸡蛋)查找临界楼层中做了详细讲解,本文将继续研究相关问题. 假如题目不要求给出具体的最优查找策略,只问最坏情况下至少需要 ...
- 算法题:鸡蛋掉落(leetcode 887题)
题目: 鸡蛋掉落 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 < ...
- 每日一题 11.4 鸡蛋掉落
每日一题 11.4 鸡蛋掉落 一.题目概述 这是一道困难题,难度肯定是比前三天的要大的,这个毋庸置疑,但是毕竟趣味性在这里摆着,和昨天那个相比,钻研这个的兴趣要更大一点,昨天那个并查集和哈希表实在是太 ...
最新文章
- java注解返回不同消息,Spring MVC Controller中的一个读入和返回都是JSON的方法如何获取javax.validation注解的异常信息...
- C# 写入和读出文本文件
- 【渝粤教育】国家开放大学2018年春季 8638-22T薪酬制度与薪酬管理 参考试题
- mysql schema是什么_MySQL中information_schema是什么
- showdoc如何创建文件夹_showDoc生成文档
- 61笔记本配置_最清晰的笔记本电脑选购推荐,每月更新(2019.5)
- SAP License:为什么新一代的财务产品不能从传统erp企业里长出来?
- MUI - 图片预览(perviewimage)的优化
- 矩阵分析 (五) 矩阵的分解
- [国嵌攻略][068][tftp网络协议实现]
- 【技术专题研究】OSPF的LSA类型
- list add java_list.add()和list.addAll()的区别
- 机器学习--组合分类方法之随机森林算法原理和实现(RF)
- 一定要跟你喜欢的人去一次“稻城亚丁”好吗!
- AHRS、IMU和INS对比
- 【模拟IC】时钟馈通效应减小及仿真验证
- snipaste滚动截图方法_老板让你把整个网页截图形成长图,具体怎么做?
- java 腾讯地图api,腾讯地图API详解
- 信奥中的数学基础:分解质因数
- HTML5前端开发实战08-外语培训