动态规划的理解(DP)

article/2025/9/29 9:03:32

动态规划(DP)

文章目录

  • 动态规划(DP)
    • 1.动态规划概念
    • 2.最短路径问题
    • 3.动态规划和分治区别
    • 4.为什么动态规划往往从后往前?

1.动态规划概念

在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。因此各个阶段决策的选取不能任意确定,它依赖于当前面临的状态,又影响以后的发展。当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线.这种把一个问题看作是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问题称为多阶段决策问题。在多阶段决策问题中,各个阶段采取的决策,一般来说是与时间有关的,决策依赖于当前状态,又随即引起状态的转移,一个决策序列就是在变化的状态中产生出来的,故有“动态”的含义,称这种解决多阶段决策最优化的过程为动态规划方法

动态规划核心思想:化繁为简,将大问题拆解成一堆小问题,该小问题的解会被重复调用,动态规划通过保存子问题最优解,避免了重复计算,提高了效率,降低时间复杂度,但同时增加了空间复杂度。


2.最短路径问题

问题描述:给定一个矩阵m,从左上角开始每次只能(上下左右)走一步,如遇边界则不可走,最后达到右下角的位置,路径中所有数字累加起来就是路径和,返回所有路径的最小路径和。
在这里插入图片描述

为方便描述按XY方向编号,假设从起始点(0,0)到目标点(4,4)需要走n步(在不考虑回头的情况下,不选择已经走过的路,从表格中可以看出总共就是走6步),每一步路径长度对应表格中的数值,记为 C n {C_n} Cn,每一步在p位置上对应的总路径长度 f ( p ) ( n ) {f_{(p)}}(n) f(p)(n),直接看一下动态规划的过程。

动态规划过程:

从目标终点往回看。
n = 6
f ( 4 , 4 ) ( 6 ) = 0 {f_{(4,4)}}(6) = 0 f(4,4)(6)=0,从目标点(4,4)出发,有两个选择。

n = 5

f ( 3 , 4 ) ( 5 ) = f ( 4 , 4 ) ( 6 ) + 1 = 1 {f_{(3,4)}}(5) = {f_{(4,4)}}(6) + 1=1 f(3,4)(5)=f(4,4)(6)+1=1
f ( 4 , 3 ) ( 5 ) = f ( 4 , 4 ) ( 6 ) + 4 = 4 {f_{(4,3)}}(5) = {f_{(4,4)}}(6) + 4=4 f(4,3)(5)=f(4,4)(6)+4=4
在这里插入图片描述

n=4

对于(3,3),可以从(4,3)到达,总路径为: f ( 4 , 3 ) → ( 3 , 3 ) ( 5 ) = f ( 4 , 3 ) ( 5 ) + 6 = 10 {f_{(4,3) \to (3,3)}}(5) = {f_{(4,3)}}(5) + 6=10 f(4,3)(3,3)(5)=f(4,3)(5)+6=10
也可以从(3,4)到达,总路径为: f ( 3 , 4 ) → ( 3 , 3 ) ( 5 ) = f ( 3 , 4 ) ( 5 ) + 1 = 7 {f_{(3,4) \to (3,3)}}(5) = {f_{(3,4)}}(5) + 1=7 f(3,4)(3,3)(5)=f(3,4)(5)+1=7
显然,想要从目标点(4,4)到达(3,3),最优的选择是从(3,4)这一点,所以放弃另外路线。
f ( 2 , 4 ) ( 4 ) = f ( 3 , 4 ) ( 5 ) + 2 = 3 {f_{(2,4)}}(4) = {f_{(3,4)}}(5) + 2=3 f(2,4)(4)=f(3,4)(5)+2=3
f ( 3 , 3 ) ( 4 ) = f ( 3 , 4 ) ( 5 ) + 6 = 7 {f_{(3,3)}}(4) = {f_{(3,4)}}(5) + 6=7 f(3,3)(4)=f(3,4)(5)+6=7
f ( 4 , 2 ) ( 4 ) = f ( 4 , 3 ) ( 5 ) + 8 = 12 {f_{(4,2)}}(4) = {f_{(4,3)}}(5) + 8=12 f(4,2)(4)=f(4,3)(5)+8=12
在这里插入图片描述

到这里其实动态规划的优势已初见端倪,我们将整个大的问题,切分成了若干个小的子问题,通过迭代的方式依次求出子问题最优解,所有子问题的最优解之和不一定是全局最优解,但全局最优解一定包含着若干局部最优解。当我们计算每一阶段的目标函数 f ( n ) f(n) f(n)时,只需要用上一阶段的目标函数值加上对应路径长度,即 f ( n ) = f ( n + 1 ) + C ( n ) f(n) = f(n + 1) + C(n) f(n)=f(n+1)+C(n)
你可能会说:“这有啥,跟暴力搜索有啥区别?”
示例很简单,可以一眼看出下一节点的目标函数值 f ( n ) f(n) f(n),想象一下如果f(6)后面还有10万个节点,那么每一次前进都要遍历一遍前面的路径,这包含了很多重复的计算,计算量也是无法接受的。可以想象如果要从(3,3)前往(4,4)(子问题),中间有很多条路线,我们只需要计算一遍并记住最短的一条(最优解)即可,从而避免了重复的计算(搜索)。
在这里插入图片描述
小结一下,动态规划通过将问题切分,化繁为简,使得每一个子问题小到可以轻松计算,记录节点(子问题的最优解)的值,快速迭代产生下一节点的值,免去了重复的计算(搜索)。当然这也付出一定代价,需要(内存)记住节点上所有的可行解,当可行解多到(内存)记不住时,这又是另一话题了。

动态规划算法的关键在于解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其他的算法。选择动态规划算法是因为动态规划算法在空间上可以承受,而搜索算法在时间上却无法承受,所以我们舍空间而取时间。

n=3
同理,根据 f ( n ) = f ( n + 1 ) + C ( n ) f(n) = f(n + 1) + C(n) f(n)=f(n+1)+C(n)依次计算各个目标函数值。
f ( 1 , 4 ) ( 3 ) = f ( 2 , 4 ) ( 4 ) + 9 = 12 {f_{(1,4)}}(3) = {f_{(2,4)}}(4) + 9=12 f(1,4)(3)=f(2,4)(4)+9=12
f ( 2 , 3 ) ( 3 ) = f ( 2 , 4 ) ( 4 ) + 3 = 6 {f_{(2,3)}}(3) = {f_{(2,4)}}(4) + 3=6 f(2,3)(3)=f(2,4)(4)+3=6
f ( 3 , 2 ) ( 3 ) = f ( 3 , 3 ) ( 4 ) + 1 = 8 {f_{(3,2)}}(3) = {f_{(3,3)}}(4) + 1=8 f(3,2)(3)=f(3,3)(4)+1=8
f ( 4 , 1 ) ( 3 ) = f ( 4 , 2 ) ( 4 ) + 8 = 20 {f_{(4,1)}}(3) = {f_{(4,2)}}(4) + 8=20 f(4,1)(3)=f(4,2)(4)+8=20
在这里插入图片描述
n=2
f ( 1 , 3 ) ( 2 ) = f ( 2 , 3 ) ( 3 ) + 5 = 11 {f_{(1,3)}}(2) = {f_{(2,3)}}(3) + 5=11 f(1,3)(2)=f(2,3)(3)+5=11
f ( 2 , 2 ) ( 2 ) = f ( 2 , 3 ) ( 3 ) + 1 = 7 {f_{(2,2)}}(2) = {f_{(2,3)}}(3) + 1=7 f(2,2)(2)=f(2,3)(3)+1=7
f ( 3 , 1 ) ( 2 ) = f ( 3 , 2 ) ( 3 ) + 5 = 13 {f_{(3,1)}}(2) = {f_{(3,2)}}(3) + 5=13 f(3,1)(2)=f(3,2)(3)+5=13
在这里插入图片描述
n=1
f ( 1 , 2 ) ( 1 ) = f ( 2 , 2 ) ( 2 ) + 3 = 10 {f_{(1,2)}}(1) = {f_{(2,2)}}(2) + 3=10 f(1,2)(1)=f(2,2)(2)+3=10
f ( 2 , 1 ) ( 1 ) = f ( 2 , 2 ) ( 2 ) + 6 = 13 {f_{(2,1)}}(1) = {f_{(2,2)}}(2) + 6=13 f(2,1)(1)=f(2,2)(2)+6=13
在这里插入图片描述
至此,可以得到最短路径:0-3-1-3-2-1-0, f = 10 f=10 f=10
在这里插入图片描述

3.动态规划和分治区别

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
动态规划算法:它通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。

分治法:若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。

总而言之就是,只要之前计算过的结果,动态规划都会保存结果,而再次用到时不会再算一遍,而是直接调用结果。


4.为什么动态规划往往从后往前?

在这里插入图片描述
两种方法得到的算法具有相同的渐近运行时间,仅有的差异是在某些特殊情况下,自顶向下方法有可能并未真正递归地考察所有可能的子问题。由于没有频繁的递归函数调用的开销,自底向上的方法的时间复杂性函数通常具有更小的系数。
(以上图片来自 算法导论 第15章动态规划。)

简单的来说,带备忘的自顶向下法即遇到什么就求什么,求完把结果保存起来,下次用到的时候直接读取结果。自底向上也类似,不过是按参数顺序求解函数,从结果反推,先求小的再求大的。


http://chatgpt.dhexx.cn/article/1LajWHIF.shtml

相关文章

动态规划(DP)小结

目录 动规解题的一般思路 能用动规解决的问题的特点 动归的常用形式 例题 例题一:最长公共子序列 例题二:最大子段和 例题三:最长上升子序列(最长单调递增) 例题四:数字三角形 例题五 0-1背包问题 应用题 应用一&#x…

动态规划 DP专题

跟着ygg的dp题单刷的dp 1.代码源每日一题 Div1 连续子序列 分析&#xff1a; dp数组开成map&#xff0c;则状态转移式dp[i] max(dp[i - 1] 1, dp[i]) AC代码&#xff1a; #include <bits/stdc.h>using namespace std; typedef long long ll; #define int ll #define …

动态规划之线性DP

&#x1f40f;&#x1f40f;&#x1f40f; &#x1f40f;动态规划之线性DP&#x1f40f;&#x1f40f;写在前面&#x1f40f;&#x1f40f;数字三角形&#x1f40f;&#x1f40f;最长上升子序列&#x1f40f;&#x1f40f;最长上升子序列 II&#x1f40f;&#x1f40f;最长公共…

DP(动态规划)入门基础详解

DP总结&#xff08;写得这么辛苦点个赞呗&#xff01;&#xff09; DP基本概要&#xff1a; 动态规划算法把原问题视作若干个重叠子问题的逐层递进,每一个子问题的求解过程都构成一个“阶段”。在完成前一个阶段的计算后,动态规划才会执行下一阶段的计算。 无后效性 &#xf…

非常好的动态规划(DP)总结

转自&#xff1a; http://cppblog.com/menjitianya/archive/2015/10/23/212084.html 目录 一、动态规划初探 1、递推 2、记忆化搜索 3、状态和状态转移 4、最优化原理和最优子结构 5、决策和无后效性 二、动态规划的经典模型 1、线性模型 2、区间模型 3、背包模型 4、状态压…

动态规划 DP (一)

1.动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09; 维基百科的定义说的很清楚&#xff1a; 动态规划不能解决所有的问题&#xff0c; 只能应用于有最优子结构的问题。例如背包问题、最长公共子序列问题、最短路径问题等。 最优子结构&#xff1a;局部…

动态规划(DP)通俗讲解

参考 徐凯强 Andy 动态规划中递推式的求解方法不是动态规划的本质。 我曾经作为省队成员参加过NOI&#xff0c;保送之后也给学校参加NOIP的同学多次讲过动态规划&#xff0c;我试着讲一下我理解的动态规划&#xff0c;争取深入浅出。希望你看了我的答案&#xff0c;能够喜欢上动…

【算法之动态规划(一)】动态规划(DP)详解

一、基本概念 动态规划(dynamic programming)是 运筹学 的一个分支&#xff0c;是求解决策过程(decision process)最优化的数学方法。20世纪50年代初 美国 数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时&#xff0c;提出了著名的最优…

动态规划(dp)的总结

动态规划(dp)的总结 动态规划只要找到子问题&#xff0c;写起来就很简单&#xff0c;通常最多就二维dp数组即可解决问题&#xff0c;顶多再来个双dp&#xff0c;再加点逆向思维……下面列出我见过的子问题&#xff0c;别栽在dp上了&#xff0c;求求了。 能用dp做&#xff0c;…

数据结构与算法——动态规划(DP)

文章目录 1. 应用场景2. DP状态2.1 最优子结构2.2 无后效性2.3 解题思路 3. 问题类别3.1 线性DP3.1.1 经典问题3.1.1.1 [LeetCode 300. 最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/)3.1.1.2 [LeetCode 1143. 最长公共子序列](https://l…

关于动态规划(dp)

**动态规划(DP) 一.基本概念 动态规划&#xff08;英语&#xff1a;Dynamic programming&#xff0c;简称DP&#xff09;是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的&#xff0c;通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 它针对满足…

动态规划(DP)的原理、实现及应用

文章目录 1. 由一个例子说开&#xff1a; 斐波那契&#xff08;fibonacci&#xff09;数列 性能测试原因分析2. 记忆化搜索3. 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09; 最优子结构总结一下这几个解法&#xff1a;几个例题 LeetCode 70 Climbing St…

Hi3519AV100与Hi3559AV100在芯片规格 上主要差异

表1-1简要对比了Hi3519AV100与Hi3559AV100在规格方面的差异&#xff0c;Hi3519AV100的具体规格请参见《Hi3519AV100 ultra-HD Mobile Camera SoC 用户指南》。

海思平台(hi3559av100)异构多系统的使用Linux(2*A53+2*A73)+liteos(A53)+liteos(M7)

在文档《SDK安装及升级使用说明》中有对linuxliteos异构多系统的烧写有介绍。这里对其中的一些注意的地方记录以下&#xff0c;以备查验。 由于我的目标是要搭建一个ISP调试环境&#xff0c;就是使用海思的ittp_stream工具能够连接上开发板&#xff0c;并能够实时查看摄像头的…

M302H-ZN-Hi3798MV300/MV300H-当贝纯净桌面-卡刷固件包

M302H-ZN-Hi3798MV300&#xff0f;MV300H-当贝纯净桌面-卡刷固件包-内有教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用…

华为海思 hikey970 详细介绍

前几天申请到了华为的开发板&#xff1a;hikey970 用来做项目的。 板子是这样的: 下面是在网中收集到的信息总结&#xff1a; 基于麒麟970的AI智慧算力&#xff0c;HiKey 970除了支持CPU和GPU的AI运算外&#xff0c;还支持基于NPU的神经网络计算硬件加速。 公开资料显示&am…

海思Hi3519AV100 emmc flash方式 linux系统移植 hitool工具烧写

因为我这里的海思文档只有SPI NOR Flash方式的详细烧写步骤&#xff0c;没有emmc方式的&#xff0c;本文提供一个自己成功的案例仅供参考和记录 1. 准备SDK、安装交叉编译工具、编译osdrv 1.1 解压SDK包 将Hi3519AV100_SDK_Vx.x.x.x.tgz文件放入ubuntu系统下&#xff08;wind…

海思3559:MMZ内存、OS内存配置

前言 海思3559的DDR最大支持到8GB hi3559av100芯片的内存地址范围 (1)通过查阅数据手册可知《Hi3559AV100 专业型 Smart IP Camera SoC 用户指南》&#xff0c;芯片的内存地址范围是0x4000_0000-0x23FFF_FFFF&#xff0c;最大能支持8G内存&#xff1b;   (2)海思芯片把内存分…

劲爆!java架构师百度网盘

第一份资料:Kafka实战笔记 Kafka入门为什么选择KafkaKarka的安装、管理和配置Kafka的集群第一个Kafka程序afka的生产者 Kafka的消费者深入理解Kafka可靠的数据传递

10本Java架构师必读书籍推荐

##### 1.《大型网站系统与Java中间件开发实践》 本书围绕大型网站和支撑大型网站架构的 Java 中间件的实践展开介绍。从分布式系统的知识切入&#xff0c;让读者对分布式系统有基本的了解&#xff1b;然后介绍大型网站随着数据量、访问量增长而发生的架构变迁&#xff1b;接着…