您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

时间:2020-03-15 13:22:22  来源:  作者:

动态规划的重要性就不多说,直接进入正题

首先,我们看一下官方定义:

定义:

动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。

动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

基本思想与策略编辑:

由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。

(来自百度百科)

说实话,没有动态规划的基础很难看懂,但是也能从中看出一些信息,下面我翻译成人话:

首先是拆分问题,我的理解就是根据问题的可能性把问题划分成一步一步这样就可以通过递推或者递归来实现.

关键就是这个步骤,动态规划有一类问题就是从后往前推到,有时候我们很容易知道:如果只有一种情况时,最佳的选择应该怎么做.然后根据这个最佳选择往前一步推导,得到前一步的最佳选择

然后就是定义问题状态和状态之间的关系,我的理解是前面拆分的步骤之间的关系,用一种量化的形式表现出来,类似于高中学的推导公式,因为这种式子很容易用程序写出来,也可以说对程序比较亲和(也就是最后所说的状态转移方程式)

我们再来看定义的下面的两段,我的理解是比如我们找到最优解,我们应该讲最优解保存下来,为了往前推导时能够使用前一步的最优解,在这个过程中难免有一些相比于最优解差的解,此时我们应该放弃,只保存最优解,这样我们每一次都把最优解保存了下来,大大降低了时间复杂度

说很难理解清楚,容易懵懵懂懂的,所以下面结合实例看一下(建议结合实例,纸上谈兵不太好):

经典的数字三角形问题(简单易懂,经典动态规划);

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 


经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 

可以看出每走第n行第m列时有两种后续:向下或者向右下

由于最后一行可以确定,当做边界条件,所以我们自然而然想到递归求解

解题思路:

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 


经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 

下面简单写一下JAVA代码:

//java代码纯属自己练习,标准答案参考上面的C语言答案
class solution{
	public int getMax(){
		int MAX = 101;
		int[][] D = new int[MAX][MAX];   //存储数字三角形
		int n;              //n表示层数
		int i = 0; int j = 0;
		int maxSum = getMaxSum(D,n,i,j);
		return maxSum;
	}
	public int getMaxSum(int[][] D,int n,int i,int j){
		if(i == n){
			return D[i][j];
		}
		int x = getMaxSum(D,n,i+1,j);
		int y = getMaxSum(D,n,i+1,j+1);
		return Math.max(x,y)+D[i][j];
	}
}

其实仔细观察,上面的解答过程时间复杂度难以想象的大,那是因为他对有的数字的解进行了多次的重复计算,具体如下图:

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 

如果不明白上图,可以把每条路径都画出来,观察每个数字有多少条路径经过了他,就会一目了然

然后我们就可以自然而然的想到,如果我们每次都把结果保存下来,复杂度就会大大降低

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 

其实答案很简单:

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 

其实,仔细观察该解题过程,该过程就是标准的动态规划解题过程,如果把该过程画出来(找到每一步的最优解,其他的舍弃)对动态规划会有更深刻的解法

还有就是,递推的另一个好处是可以进行空间优化,如图:

经典中的经典算法,动态规划(详细解释,从入门到实践,逐步讲解)

 

下面总结一下动态规划的解题一般思路:

首先递归应该是我们解决动态规划问题最常用的方法,帅,速度不算太慢

那么递归到动规的一般转化方法为:

如果该递归函数有n个参数,那么就定义一个n维数组,数组下标是递归函数参数的取值范围(也就是数组每一维的大小).数组元素的值就是递归函数的返回值(初始化为一个标志值,表明还未被填充),这样就可以从边界值开始逐步的填充数组,相当于计算递归函数的逆过程(这和前面所说的推导过程应该是相同的).

动规解题的一般思路(标准官方,不过经过前边讲解应该就能理解了):

将原问题分解为子问题(开头已经介绍了怎么分解)

(注意:1,子问题与原问题形式相同或类似,只是问题规模变小了,从而变简单了;

2,子问题一旦求出就要保存下来,保证每个子问题只求解一遍)

确定状态(状态:在动规解题中,我们将和子问题相关的各个变量的一组取值,称之为一个"状态",一个状态对应一个或多个子问题所谓的在某个状态的值,这个就是状态所对应的子问题的解,所有状态的集合称为"状态空间".我的理解就是状态就是某个问题某组变量,状态空间就是该问题的所有组变量) 另外:整个问题的时间复杂度就是状态数目乘以每个状态所需要的时间

确定一些初始状态(边界条件)的值 (这个视情况而定,千万别以为就是最简单的那个子问题解,上面只是例子,真正实践动规千变万化)

确定状态转移方程 (这一步和第三步是最关键的 记住"人人为我"递推,由已知推未知)

适合使用动规求解的问题:

1,问题具有最优子结构

2,无后效性 说的花里胡哨的,其实一般遇到求最优解问题一般适合使用动态规划



Tags:动态规划   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言递归,是一个非常重要的概念,也是面试中非常喜欢考的。因为它不但能考察一个程序员的算法功底,还能很好的考察对 时间空间复杂度 的理解和分析。本文只讲一题,也是几乎所有算...【详细内容】
2020-09-21  Tags: 动态规划  点击:(61)  评论:(0)  加入收藏
动态规划的重要性就不多说,直接进入正题首先,我们看一下官方定义:定义:动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决...【详细内容】
2020-03-15  Tags: 动态规划  点击:(54)  评论:(0)  加入收藏
算法是一种艺术,给人感觉很不好接近,但是一旦你和ta熟络了,你就能发现这门艺术的内在是多么美妙且多变。对于前端来说,算法也许不是最重要的,在日常工作中,几乎很少用到。所以很多...【详细内容】
2019-12-23  Tags: 动态规划  点击:(70)  评论:(0)  加入收藏
假设你正在使用适当的输入数据进行一些计算。你在每个实例中都进行了一些计算,以便得到一些结果。当你提供相同的输入时,你不知道会有相同的输出。这就像你在重新计算之前已经计算好的特定结果一样。...【详细内容】
2019-08-28  Tags: 动态规划  点击:(194)  评论:(0)  加入收藏
前言动态规划动态规划动态规划其实就是对分而治之策略的一种应用, 将一个较大的问题分解成有限个的不相关的子问题问题, 然后通过解决子问题, 不断推演出最终结果。动态规划...【详细内容】
2019-08-21  Tags: 动态规划  点击:(329)  评论:(0)  加入收藏
递归算法与动态规划算法是计算机程序设计、数据结构中常见算法。有些书籍教材中对递归算法与动态规划算法比较时,总是指出动态规划算法优于递归算法,在问题较为复杂时不建议使...【详细内容】
2019-06-19  Tags: 动态规划  点击:(416)  评论:(0)  加入收藏
▌简易百科推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Java技术那些事    Tags:时间轮   点击:(1)  评论:(0)  加入收藏
博雯 发自 凹非寺量子位 报道 | 公众号 QbitAI在炼丹过程中,为了减少训练所需资源,MLer有时会将大型复杂的大模型“蒸馏”为较小的模型,同时还要保证与压缩前相当的结果。这就...【详细内容】
2021-12-24  量子位    Tags:蒸馏法   点击:(11)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  老师明明可以靠颜值    Tags:算法   点击:(7)  评论:(0)  加入收藏
1. 基本概念希尔排序又叫递减增量排序算法,它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的;希尔排序是一种不稳定的排序算法...【详细内容】
2021-12-22  青石野草    Tags:希尔排序   点击:(6)  评论:(0)  加入收藏
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  星云博创    Tags:栈迁移   点击:(22)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15    晓掌柜丶韶华  Tags:排序算法   点击:(16)  评论:(0)  加入收藏
在了解golang的map之前,我们需要了解哈希这个概念。哈希表,又称散列表(Hash table),是根据键(key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将...【详细内容】
2021-12-07  一棵梧桐木    Tags:哈希表   点击:(14)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯·奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  小心程序猿QAQ    Tags:雪花算法   点击:(24)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  华章科技    Tags:排序算法   点击:(40)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  有AI野心的电工和码农    Tags: KMP算法   点击:(36)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条