动态规划经典题目_动态规划经典题目:鸡蛋掉落(附视频讲解)
题目:
思路:
先放上视频讲解
动态规划经典题目:鸡蛋掉落https://www.zhihu.com/video/1225199247848513536
纠正:视频里的状态转移方程漏写了一个+1,意思就是不管鸡蛋有没有摔碎,不管我们是往上走还是往下走,当前都已经扔过一次了,所以次数+1。
代码(优化前):
class Solution {public int superEggDrop(int K, int N) {//dp存的是拥有i个鸡蛋j层楼情况下找到F所需的最小移动次数int[][] dp = new int[K+1][N+1];//只有一个鸡蛋时,最坏需要移动(当前拥有的楼层数)次for(int i=0;i<=N;i++){dp[1][i] = i;}//从两个鸡蛋的情况开始算for(int i=2;i<=K;i++){//在拥有i个鸡蛋j个楼层的情况下,计算从h层扔鸡蛋去找F层所需的移动次数for(int j=1;j<=N;j++){int ans = Integer.MAX_VALUE;for(int h=1;h<=j;h++){int A = dp[i-1][h-1];int B = dp[i][j-h];//ans为h从1取到j层楼的所有情况里的最小移动次数ans = Math.min(ans,Math.max(A,B)+1);}dp[i][j] = ans;}}return dp[K][N];}
}
这是结合我视频里的思路写出来的代码,比较便于理解。但是由于h一次次地从1取到当前拥有的楼层数,然后才能比较出最小值,这中间做了很多不必要的工作,所以还需要进行优化。
回头看一下这个状态转移方程:max(dp(K-1,X-1),dp(K,N-X))
可以发现:
当X增大时,dp(K-1,X-1)是随之增大的。这也很好理解,楼层越多,想找到F就需要更多的次数。
而当X增大时,dp(K,N-X)是随之减小的。和上条是一样的道理,X越大,N-X就越小,即楼层越少,那么找到F所需的次数就更少。
而max(dp(K-1,X-1),dp(K,N-X)),取的是两者中的较大数。画个图理解一下(当然真实数据并不是图片所展示的这样,这个图只是为了便于理解):
所以max(dp(K-1,X-1),dp(K,N-X))是先递减后递增的,它的最小值即为我们要找的最小移动次数。
也就是说,我们不必每次都让h从1开始遍历完所有的楼层,只要找到一个X,使得
max(dp(K-1,X-1),dp(K,N-X))<max(dp(K-1,(X+1)-1),dp(K,N-(X+1)))
成立,那么这个X就是让max取到最小值时的层数。
代码(优化后):
class Solution {public int superEggDrop(int K, int N) {//dp存的是拥有i个鸡蛋j层楼情况下找到F所需的最小移动次数int[][] dp = new int[K+1][N+1];//只有一个鸡蛋时,最坏需要移动(当前拥有的楼层数)次for(int i=0;i<=N;i++){dp[1][i] = i;}//从两个鸡蛋的情况开始算for(int i=2;i<=K;i++){int x=1;for(int j=1;j<=N;j++){//当取x层比取X+1层的结果要大时,x++(再往上找)while(x<j && Math.max(dp[i-1][x-1],dp[i][j-x])>Math.max(dp[i-1][x],dp[i][j-x-1]))x++;dp[i][j] = Math.max(dp[i-1][x-1],dp[i][j-x])+1;}}return dp[K][N];}
}
总结:动态规划就是一个自底向上计算的过程,保存每个前面的值,便于后面去计算。像这道题,我们先算好K=1的情况,便于给K=2的情况用。接下来,一步步根据前面的值算出dp[2][1],dp[2][2]……就这样一直自底向上计算出dp[K][N]。
补充:经评论区大神指点,发现还可以做另一种优化。
像上面分析的那样,dp(K-1,X-1)是递增函数,dp(K,N-X)是递减函数,max在两者相交时取到最小值。如下图所示。
那么我们令low=1,high=N(当前总楼层数),index=(low+high)/2,根据以上图像,我们会发现:
如果dp(K-1,index-1)>dp(K,N-index),说明当前index位于交点右侧,可以缩小查找区间至[low,index],否则说明index位于交点的左侧,缩小查找区间为[index,high]。
根据这个规律,就可以通过二分法去查找到这个交点了!
代码(优化二):
class Solution {public int superEggDrop(int K, int N) {//dp存的是拥有i个鸡蛋j层楼情况下找到F所需的最小移动次数int[][] dp = new int[K+1][N+1];//只有一个鸡蛋时,最坏需要移动(当前拥有的楼层数)次for(int i=0;i<=N;i++){dp[1][i] = i;}//从两个鸡蛋的情况开始算for(int i=2;i<=K;i++){for(int j=1;j<=N;j++){//通过二分法去查找能取到最小移动次数的层数int low=1,high=j;while(low+1<high){int index = (low+high)/2;int A = dp[i-1][index-1];int B = dp[i][j-index];if(A>B){high = index;}else if(A<B){low = index;}else{low = high = index;}}//dp[i][j]=min(选择low层时的移动次数,选择high层时的移动次数)dp[i][j] = Math.min(Math.max(dp[i-1][low-1],dp[i][j-low]),Math.max(dp[i-1][high-1],dp[i][j-high]))+1;}}return dp[K][N];}
}
注意:这个交点可能并不是整数(无法取到这个楼层),所以最后要用low和high分别代入计算,再取最小值。
最后的一点感想:终于写完了。。。曾经让我望而却步的算法,现在也能轻松掌握了,还是很有成就感的~其实学这些真的没有那么难,只要多一点耐心和毅力,相信自己就好。
最后借用添哥一句话吧:
我无坚不摧,也无所不能。
与君共勉~
动态规划经典题目_动态规划经典题目:鸡蛋掉落(附视频讲解)相关推荐
- 动态规划走楼梯_动态规划问题为什么要画表格?
❝ 本文是我的 91 算法第一期的部分讲义内容.91 算法第一期已经接近尾声,二期的具体时间关注我的公众号即可,一旦开放,会第一时间在公众号<力扣加加>通知大家. ❞ 动态规划可以理解为是 ...
- java 动态规划找零钱_动态规划之找零钱问题
找零钱是一个经典的动态规划问题.这种问题,我建议,首先学会暴力解法,然后从暴力解法中优化出动态规划的解法,这样,更能体会动态规划的魅力. 问题描述 有n种不同币值的硬币,硬币数量无限.给定一个数量T, ...
- python用动态规划求最短路径_动态规划之最短路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [ [1,3,1], [1,5,1], ...
- 信度和效度经典例子_浅析经典目标检测评价指标--mmAP(一)
大家好,我是旷视科技南京研究院研究员赵博睿,主要研究领域为目标检测.今天和大家聊聊mmAP的那些事- 目标检测是计算机视觉领域的一项基础问题,在许多智能场景的落地应用中目标检测通常都是视觉感知的第一步 ...
- 递归算法经典实例_【经典算法】利用递归方法求5!
找出数组只出现一次的数字 题目 利用递归方法求5! 示例: 输入: 5!输出: 120 思路: 当传入5时,5>1,所以返回recursion(4)*5; recursion(4)则调用recu ...
- python网络安全论文题目_自动化毕业论文题目119个免费参考
自动化毕业论文题目119个免费参考时间:2016-06-12 来源:未知 作者:chunt 本文字数:2522字 自动化专业有三个方向,工业自动化控制.电气自动化及自动化嵌入系统设计,选题可从这些方向 ...
- 男人帮经典台词_男人帮经典语录大全
电视剧<<男人帮>>正在火热上映,男人帮里的经典台词也被火热传播着,本文就收集了男人帮经典台词供大伙欣赏,很值得一看的电视剧哦.下面就来看看男人帮经典语录吧. 男人帮经典台词大 ...
- 基于神经网络的毕设题目_自动化毕业设计题目
做毕业设计之前一定要学好题目,下面是关于自动化毕业设计题目,希望对大家有帮助! 1.视觉图像采集及处理研究 2.基于J2ME平台手机系统扩展软件开发 3.柔性加工自动线的设计 4.采用氧量-热量信号的 ...
- java动态规划货车运输_动态规划01背包问题_动态规划方法在配送线路优化中的应用研究...
[摘要] 应用图论的方法对配送线路进行优化的缺点是,当线路复杂时计算较为烦琐,而应用动态规划的方法能有效解决这个问题.本文从理论上应用动态规划的方法对共同配送线路进行优化,并应用此方法对实际问题进行计 ...
最新文章
- Javascript笔记02:严格模式的特定要求
- linux 搭建 lamp环境搭建,Worktile官方博客,分享企业协作的技巧、工具和实践
- [c语言 ] 用libev 写个echo服务器
- 入职阿里啦!docker-e命令参数
- [git] git fsck --lost-found命令用法
- 定位html中的背景图,关于背景图的定位和透明度问题(HTML+CSS笔记)
- 数据3分钟丨​PingCAP DevCon 2021回顾;openGauss社区颁发首张OGCA认证证书
- HTC公布第二款区块链手机Exodus 1s:或将于9月前发售
- golang 定义一个空切片_Golang slice切片操作之切片的追加、删除、插入等
- ie型lfsr_什么是PRBS
- Spring-boot + Mybatis-plus 3.0-gamma 配置记录
- 最详细的Java入门完整教程,学Java先收藏了!
- 安装moodle3.6
- win7计算机桌面快捷键显示桌面,win7系统右击桌面快捷小工具使用介绍
- THREE.JS 导入STL格式的模型
- 路由器 mac 和 bssid是一个吗
- D盘或者E盘根目录出现msdia80.dll文件的解决方法
- Vue 背景音乐点击随机播放
- 如何增加微信阅读量,新手公众号如何增加阅读量
- [Nodejs入门]第四篇,用nodejs实现一个爬虫的功能
热门文章
- iview兼容ie8_如何解决iview在安卓4.4.4的webview中的兼容性
- 【总议程】2021全球分布式云大会·上海站明日开幕!墨天轮将全程线上直播
- 技术生态两手抓,打造面向未来的企业级领先数据库
- 清明节特辑 |记忆存储、声音还原、性格模仿……AI可以让人类永生吗?
- 【华为云技术分享】云图说 | 云硬盘还可以共享?!不了解你就out了
- 浅谈云网融合与SD-WAN
- Zabbix的应用(6)----常见错误
- mysql ddl分类_MySQL语言分类——DDL
- mysql5.7 glibcxx_3.4.15_Percona Server安装可能出现的问题 version `GLIBCXX_3.4.15' not found ...
- 运用时间增益方法对 gprmax 模拟的探地雷达数据进行处理