理论+实践,带你掌握动态规划法
本文分享自华为云社区《五大基础算法--动态规划法》,作者: 大金(内蒙的)。
一、基本概念
动态规划法,和分治法极其相似。区别就是,在求解子问题时,会保存该子问题的解,后面的子问题求解时,可以直接拿来计算。
专业的说法是:
对于一个规模为n的问题,将其分解为k个规模较小的子问题(阶段),按顺序求解子问题,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,通过决策求得局部最优解,依次解决各子问题。最后可以通过简单的判断,得到原问题的解。
说法有些晦涩难懂,我给大家解释下:
阶段:求解第n个子问题称为第n个阶段。动态规划是按照顺序去求解子问题的,这里子问题的求解顺序很重要。
状态:在求解第n个阶段时,已求解n-1个阶段的解,称为状态。
决策:在求解第n个阶段时,根据状态和计算规则,可以得到第n个阶段时解。
二、基本特征
动态规划法所能解决的问题一般具有以下几个特征:
1) 大问题可分解性
该问题可以分解为若干个规模较小的问题,即该问题具有最优子结构性质。
2) 子问题易解决性
该问题的规模缩小到一定的程度就可以容易地解决
3) 解可合并性
利用该问题分解出的子问题的解可以合并为该问题的解;
4) 子问题重叠性
当计算出某个子问题的解时,后续多个问题都需要计算该子问题的解,所以在计算某个子问题的解,将其保存,就节省了分治法重复计算的时间。
三、一些误解
1.状态转移方程
很多博客都说什么状态转移方程,感觉说的很高大上,一般解题上来就是状态转移方程是xxxx,代码是xxxx,翻译下是什么意思呢?
在求解第n个子问题的时候,通过已求解n-1个阶段的解和计算规则,可以得到第n个阶段时解。
即是最新的状态=目前的状态+决策。
2.初始化
很多题目解题的时候都说初始化,这并不是动态规划法的步骤。应该正确的去理解这些操作。动态规划在划分子问题求解顺序时,基本是先求解易求解最小的子问题,在由这些已经求解的阶段+计算规则,就能直接求得第n阶段的解。所以初始化的含义是,求得初始阶段的解。
3.边界条件
一般题目会说边界是啥,可以理解为怎么判断所有的子问题已经求解结束了。正常人也不会写while(true)吧,你总得让程序结束,判断你已经解决好这个问题了。
四、动态规划法的基本步骤
step1 分解:
将一个问题分解为多个子问题,需要注意子问题解决的顺序,应该先求解易求解的子问题,且后续的阶段可以通过前面的阶段+决策得到。
step2 状态转移:
通过得到的规律,写出状态转移方程。
第n阶段=当前状态+决策(前n个阶段解和计算规则)
step3 写代码:
将最先算的阶段计算出来,中间阶段通过状态转移方程计算状态,直到所有阶段计算结束。
step4 得到解:
所有阶段计算结束,可以通过简单的统计,例如Max,Min等遍历阶段的值,得到最后的解。
五、经典问题
好记性不如烂笔头,有一些适用动态规划法的问题,可以帮我们不断强化的解题思想。在解决问题时,希望大家可以注意判断题目的解决思路,看是否符合动态规划法的四个特征,这样不断强化,才能将算法掌握。
(1)最长回文子串
下面附上我的题解:
https://leetcode-cn.com/problems/longest-palindromic-substring/solution/dong-tai-gui-hua-fa-qiu-jie-kan-bu-dong-octkt/
//动态规划法两个基本要素:最优子结构性质和子问题重叠性质。
//很多答案写了初始化和边界条件,个人认为你要分清楚他的目的是什么。
//很多初始化和边界条件,是因为状态转移方程,是需要初始化的子问题的解,从而避免重复计算,说白了还是子问题重叠和最优子结构问题。
//我们应该注重某一个问题的重叠子问题分解和状态最优的决策分析。
//解题思路:
//计算某个字符串时, 如果它首尾字符相等,则它是不是回文,取决于去掉头尾之后的字符串是否为回文串。
// 如果它首尾字符不相等,则它一定不是回文
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {public String longestPalindrome(String s) {int len = s.length();// 特判if (len < 2){return s;}int maxLen = 1;int begin = 0;// 1. 状态定义// dp[i][j] 表示s[i...j] 是否是回文串,现在表示全部为0,不是回文串boolean[][] dp = new boolean[len][len];char[] chars = s.toCharArray();// 2. 子问题计算顺序:先计算短字符串,在计算长字符串,同时根据已求得的短字符串或者计算规则,可以得到长字符串的解。// 注意:s表示计算的元素顺序。// 0 1 2 3 4// 0 xx s1 s2 s4 s7// 1 xx s3 s5 s8// 2 xx s6 s9// 3 xx s10// 4 xx// 为什么这么写呢,因为你要保证保证计算某个元素时,通过状态转移方程能得到左上角元素的dp[][]。// 填表规则:先一列一列的填写,再一行一行的填,保证计算某个元素时,它左上方的单元格已经被计算出了结果// 填表规则:当然你也可以由左往右一行一行写,这样也能保证计算某个元素时,它左上方的单元格已经被计算出了结果for (int j = 1;j < len;j++){for (int i = 0; i < j; i++) {// 头尾字符不相等,不是回文串if (chars[i] != chars[j]){dp[i][j] = false;}else {// 相等的情况下// 因为考虑头尾去掉以后没有字符剩余,或者剩下一个字符的时候,肯定是回文串if (j - i -1 <= 1){dp[i][j] = true;}else {// 头尾相等,中间有大于1个元素,这个时候,我们无法直接判断他是不是回文,但是我们可以通过状态转移方程去判断// 其实这个就是在计算s8这个元素时,我们无法判断dp[1][4]在1和4位元素相等时候,整个字符串是否是回文。// 所以要通过s4去判断,s4是回文,s8就是。s4不是,那s8就不是。dp[i][j] = dp[i + 1][j - 1];}}// 只要dp[i][j] == true 成立,表示s[i...j] 是否是回文串// 此时更新记录回文长度和起始位置if (dp[i][j] && (j - i + 1 > maxLen)){maxLen = j - i + 1;begin = i;}}}// 3. 初始化 // 很多答案写了这个,这一步,我们细想,其实完全没有必要。// 因为主对角线,值是可以直接判断出来的。// 而且在求解过程中,我们的状态转移方程不会用到这个值。因为只有主对角线会用到这几个值。// 而且单个元素的子问题解,我们并不需要。// 所以,即使我这步初始化放到计算之后,甚至是直接去掉,也完全不影响结果。大家可以自己试一下// for (int i = 0; i < len; i++) {// dp[i][i] = true;// }// 4. 返回值return s.substring(begin,begin + maxLen);}
}
点击关注,第一时间了解华为云新鲜技术~
理论+实践,带你掌握动态规划法相关推荐
- 数据治理的理论实践与发展趋势
为什么80%的码农都做不了架构师?>>> 数据治理的理论实践与发展趋势 大数据时代的到来为各行业带来基于数据资产进行业务创新,管理创新的契机以及大数据技术建设需求,面向大数据环境和传 ...
- UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题
UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题 对于函数f:X→Yf:X \to Yf:X→Y,我们希望XXX是一个凸的度量 ...
- 三层交换(VLAN间互通+路由功能)+VTP+STP(PVST)综合实验(理论+实践=真实)
三层交换(VLAN间互通+路由功能)+VTP+STP(PVST) 综合实验(理论+实践=经验) [需求分析] 本实验采用双核心结构,将三层交换技术和VTP.STP.以太网通道综合一起,实现 ...
- innovus停止当前命令_Innovus教程 - Flow系列 - 摆放宏单元(理论+实践+命令)
<Innovus教程 - Flow系列 - 摆放宏单元 (理论+实践+命令)> 理论: 在Innovus里面有个新功能是mix placer,可以将Macro当成Std cell一样去自动 ...
- 第七章:Tensorflow2.0 RNN循环神经网络实现IMDB数据集训练(理论+实践)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/LQ_qing/article/deta ...
- 自然语言理解理论实践-主要的语言理解任务(一)《个人学习笔记》
自然语言理解理论实践 主要的语言理解任务 1.域检测和意图识别 2.填槽 希望能多多交流,共同学习进步 主要的语言理解任务 首先,以介绍人机对话系统中使用语言理解为目标任务,进行之后的理论和实践背景的 ...
- 开放原子教育高校师资培训(OpenHarmony物联网理论+实践)成功举办
开源项目 OpenHarmony 是每个人的 OpenHarmony 2021 年 8 月 26 日至 28 日,开放原子教育高校课程共建师资培训系列活动(OpenHarmony物联网理论+实践)成 ...
- 判断深度学习模型的稳定性_人工智能干货|一线工程师带你学习深度学习模型量化理论+实践...
2019年的最后一天,送给自己一份特殊的礼物. 模型量化作为一种能够有效减少模型大小,加速深度学习推理的优化技术,已经得到了学术界和工业界的广泛研究和应用.模型量化有 8/4/2/1 bit等,本文主 ...
- 【理论+实践】史上最全-论文中常用的图像分割评价指标-附完整代码
图像分割的评价指标非常多,论文中常用的包括像素准确率(Pixel Accuracy, PA).交并比(Intersection-Over-Union,IOU).Dice系数(Dice Coeffcie ...
最新文章
- c cin.get()的用法小结_c语言中static 用法
- Linux 上不可修改的文件和目录
- 诺基亚 IoT安全白皮书
- javascript处理事件的一些兼容写法
- bn层初始化参数_神经网络参数初始化方式
- 三星s9android recovery,三星S9+刷第三方中文twrp recovery工具和教程
- linux 进程线程拓展
- 用python画三维图、某区域的高程,python - 在PyQt中绘制具有高程和降低效果的3D矩形/多边形 - SO中文参考 - www.soinside.com...
- CentOs基础操作指令(文件所属管理和权限管理)
- Python命令行参数
- Java基础总结04-数组
- 命令(Command)模式
- 激励函数的意义和常用几个激励函数
- Ghostscript沙箱绕过(CVE-2021-3781)分析
- java web web.xml配置_web.xml配置详解
- SuperMap iDesktop常见问题解答集锦(九)
- 生命的火花盛开与如幻如梦
- [Err] 1146 [Err] 1682
- 【学习记录】SPSS问卷调查表分析法
- Unity 实现蓄力攻击
热门文章
- 编程开源_立即注册免费的在线开源编程课程
- android基础入门思考题答案,《Android移动应用基础教程》中国铁道出版社课后习题(附答案)...
- mysql locked myisam_MySql 事务 隔离级别 知识点
- python快速接手别人的代码_十步教你如何接手别人的代码!
- 项目周期一般多久_深圳app开发公司的软件开发要多久?
- hive hql文档_大数据学习路线分享hive的运行方式
- 基于ThinkPHP3.23的简单ajax登陆案例
- 数据库清空表中的数据
- golang---文件读写
- 从客户端(Content=p666/p)中检测到有潜在危险的 Request.Form 值。