【算法】动态规划中的路径问题

在这里插入图片描述

君兮_的个人主页

即使走的再远,也勿忘启程时的初心

C/C++ 游戏开发

Hello,米娜桑们,这里是君兮_,如果给算法的难度和复杂度排一个排名,那么动态规划算法一定名列前茅。今天,我们通过由简单到困难的两道题目带大家学会动态规划中的路径问题

  • 好了废话不多说,开始我们今天的学习吧!!

动态规划之路径问题

  • 一 不同路径
    • 1 题目解析
    • 2 算法原理
      • 状态表示
      • 状态转移方程
      • 初始化
        • 辅助节点初始化法
      • 填表顺序:
      • 返回值
    • 3 编写代码
  • 二 下降路径最小和
    • 1 题目解析
    • 2 算法原理
      • 状态表示
      • 状态转移方程
      • 初始化
      • 填表顺序
      • 返回值
    • 3 编写代码
  • 总结

一 不同路径

  • 原题目leetcode链接在这哦 不同路径
    在这里插入图片描述

1 题目解析

  • 如题目所示,在左上角有一个机器人,现在我们需要算出从当前位置到右下角位置一个有多少种不同的路径。
  • 注意:重点在于,我们是不能后退的,也就是说,每次进行移动时,只能朝右或者朝下移动。

题目题意理解相对比较简单,就先说到这里

2 算法原理

  • 看到这种每一步都与上面一步有所关系的题目,我们首先想到的就是动态规划算法,我们来按照之前提到的动态算法的大致解题思路来进行一步步的分析

状态表示

  • 对于这种「路径类」的问题,我们的状态表⽰⼀般有两种形式:
  • i. 从dp[i, j] 位置出发,到某个位置去;
  • ii. 从起始位置出发,到达dp [i, j] 位置。
    分析一下题意,我们需要到达指定的位置,因此这⾥选择第⼆种定义状态表⽰的⽅式:
    dp[i][j] 表⽰:⾛到dp[i, j] 位置处,此时一共有几条不同路径

状态转移方程

  • 有了上面的状态表示,我们就需要将dp每个位置的值建立一定的联系,方便我们之后的分析
  • 如果dp[i][j] 表⽰到达 [i, j] 位置的⽅法数,那么到达 [i, j] 位置之前的⼀⼩步,有两种情况:
  • i. 从dp [i, j] 位置的上⽅( dp[i - 1, j] 的位置)向下⾛⼀步,转移到 dp[i, j] 位置;
  • ii. 从 dp[i, j] 位置的左⽅( dp[i, j - 1] 的位置)向右⾛⼀步,转移到 dp[i, j] 位置。
    由于我们要求的是有多少种⽅法,结合我们上面对题目的解析,因此我们的状态转移⽅程就可以写出了:
 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 
  • 注意:这里还有一个很多初学者容易搞混的地方——很多人认为,你现在算出的是通往dp[i][j]这里不同种方法,那么dp[i][j]这一步不应该再加个1吗?
    谨记我们这里算的是方法数,不是步数,因此当然不需要+1!

初始化

  • 初始化的主要目的有两个,
  • 1.防止发生越界访问
  • 2.方便我们从已知的信息推出我们需要的信息

这里教给大家一个做动态规划会经常使用的初始化方法

辅助节点初始化法

可以在dp表最前⾯加上⼀个「辅助结点」,帮助我们初始化。使⽤这种技巧要注意两个点:

  • i. 辅助结点⾥⾯的值要「保证后续填表是正确的」;

  • ii. 「下标的映射关系」。

  • 好了,相信到这里大家还是一头雾水,下面我来展开讲讲

    • 有关辅助节点,如果放在这一题来看的话,请问我们的dp[0][0]怎么算呢?
    • 因此在本题中,我们需要「添加⼀⾏」,并且「添加⼀列」来避免上述越界情况的发生
    • 因此就有了第一点,我们的辅助节点中保存的值,必须保证对我们的题目的解答没有影响,比如在这个题需将 dp[0][1] (或者dp[1][0])的位置初始化为1 ,剩下创建的值初始化为0,这样就能保证dp[1][1]位置的初始化
      在这里插入图片描述
    • 那么为什么从dp[1][1] 开始呢?我们的辅助队列相当于在最上后最右的位置帮我们又创建了一行一列来初始化,此时机器人所处的位置就变为了dp[1][1]了
    • 有关第二点,我们加了一行一列,下标的初始位就不再是dp[0][0]了,因此我们最后返回的值也不是dp[m-1][n-1]而是dp[m][n].。在这个题中下标的映射没啥太大的影响,具体的细节我们放在下个题再讨论

填表顺序:

  • 根据状态转移⽅程和题目分析的推导来看,填表的顺序就是「从上往下」填每⼀⾏,在填写每⼀⾏的时候「从左往右」填每一列

返回值

  • 上面在辅助节点已经说过了,返回值为dp[m][n]

完成上面的算法原理分析,下面我们来具体写一下代码


3 编写代码

class Solution {
public:int uniquePaths(int m, int n) {//开辟m*n的dp表vector<vector<int>>dp(m+1);for(int i=0;i<dp.size();i++){dp[i].resize(n+1,0);}dp[0][1]=1;//初始化//状态转移方程for(int i=1;i<=m;i++){for(int j=1;j<=n;j++)dp[i][j]=dp[i-1][j]+dp[i][j-1];}return dp[m][n];}
};

在这里插入图片描述

  • 照这上面讲的算法原理一步一步照搬挺容易ac的,这里就不细讲了,重点还是放在下面这个题上

二 下降路径最小和

  • 原题leetcode链接在这里 下降路径最小和
    在这里插入图片描述

1 题目解析

  • 给你一个 n x n 的方形整数数组 matrix ,请你找出并返回通过 matrix 的下降路径的最小和 。
  • 下降路径可以从第一行中的任何元素开始,并从每一行中选择一个元素在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。

在这里插入图片描述

  • 对于两边的特殊情况,只有向右和向左可供移动

在这里插入图片描述

  • 只有中间的情况,下一行三个位置均可插入

2 算法原理

  • 一看到这种路径算不同种数啊,算最短呐,首先我们要有使用动态规划的想法

状态表示

  • 对于这种「路径类」的问题,我们的状态表⽰⼀般有两种形式:
    i. 从 [i, j] 位置出发,到达⽬标位置有多少种⽅式;
    ii. 从起始位置出发,到达[i, j] 位置,⼀共有多少种⽅式
    这⾥选择第⼆种定义状态表⽰的⽅式:
  • dp[i][j] 表示:到达[i, j] 位置时,所有下降路径中的最小和
  • 路径问题的状态表示都是类似的,这里就不多阐释了,自己写的时候记得结合一下dp表中存的值符合题目要求就行

状态转移方程

  • 先不考虑越界情况,对于普遍位置的dp[i, j] ,根据题意得,到达[i, j] 位置可能有三种情况:
    i. 从正上⽅ [i - 1, j] 位置转移到 [i, j] 位置;
    ii. 从左上⽅ [i - 1, j - 1] 位置转移到 [i, j] 位置;
    iii. 从右上⽅ [i - 1, j + 1] 位置转移到 [i, j] 位置;
  • 我们要的是三种情况下的「最⼩值」,然后再加上数组中在 [i, j] 位置的值。
    于是,我们可以得出状态转移方程
    dp[i][j] = min(dp[i - 1][j], min(dp[i - 1][j - 1], dp[i - 1][j +1])) + matrix[i][j]

初始化

  • 从我在题意分析中画的那个图,可以明显看出每一行的最左位置和最右位置都存在越界,因此为了防止出现这种情况,我们还是采用上面讲的辅助节点的方法来进行初始化,不同的是,此时两边都存在可能越界,因此我们要初始化一行两列,示意图如下:
    在这里插入图片描述
  • 在这里对辅助节点进行初始化时,我们由于是求最小下降路径,为了不影响原dp表结果,此时先把辅助节点都填上一个较大的值。
  • 此时,如果我们全都是较大的值,那么此时dp表第一行的初始化就会直接以这个较大值进行初始化,为了避免这种情况发生,我们将辅助节点的第一行全部初始化为0。
    在这里插入图片描述
    注意,重点来了:
  • 我们之前在辅助节点初始化方法中说过要注意下标的映射关系。
  • 这里,我们需要把原数组的值填入到当前这个dp表中,但是现在的dp表多了一行两列,因此我们之前dp[i][j]=min+matrix[i][j]就需要改成dp[i][j]=min+matrix[i-1][j-1] ,这样才能满足对应的下标关系

填表顺序

  • 题目已经明确告诉你了。从上到下

返回值

  • 注意这⾥不是返回 dp[m][n] 的值!
  • 题⽬要求「只要到达最后⼀⾏」就⾏了,因此这⾥应该返回「dp表中最后⼀⾏的最⼩值」

3 编写代码

class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {int n=matrix.size();//创建dp表vector<vector<int>>dp(n+1,vector<int>(n+2));//初始化for(int i=1;i<=n;i++){dp[i][0]=dp[i][n+1]=999999;}//填dp表for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){//状态转移方程int ret=min(dp[i-1][j],min(dp[i-1][j+1],dp[i-1][j-1]));//之前的值加上此时这里数组的值dp[i][j]=ret+matrix[i-1][j-1];}}//找最后一行的最小值int min1=dp[n][1];for(int i=2;i<=n;i++){if(dp[n][i]<min1)min1=dp[n][i];}return min1;}
};

在这里插入图片描述

  • 照着上面的算法原理步骤走,ac不是so easy啦

总结

  • 好啦,我们今天的内容就先到这里啦!向这种题光看是看到只能看个一知半解的,如果你想学好的话一定要自己认真把上面两个路径规划的题写好,光看很多算法中的细节是无法体会到的。
  • 有任何的问题和对文章内容的疑惑欢迎在评论区中提出,当然也可以私信我,我会在第一时间回复的!!

新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下再走呗。你们的支持就是我更新的动力!!!

**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/190862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文字、图片免费生成视频和专属数字人,你不来试试吗?

查看生成的效果&#xff1a;AI产生的视频&#xff08;关注公众号&#xff0c;获取精彩内容&#xff09; 您是否想要制作一些令人惊叹的视频&#xff0c;但又没有视频编辑的技能或经验&#xff1f;您是否想要利用人工智能的力量&#xff0c;让您的图片和声音变成动态的视频&…

如何强制任何Android应用程序进入全屏沉浸式模式(无生根)

谷歌在2012年发布了Android版本的Chrome&#xff0c;并且从未费心给它一个全屏模式。如果您厌倦了等待自己喜欢的Android应用程序提供全屏&#xff0c;则可以使用沉浸式模式自行完成。 来吧&#xff0c;谷歌&#xff0c;我真的一直在乞求你多年&#xff01;没有理由不给我们一…

【Go语言反射reflect】

Go语言反射reflect 一、引入 先看官方Doc中Rob Pike给出的关于反射的定义&#xff1a; Reflection in computing is the ability of a program to examine its own structure, particularly through types; it’s a form of metaprogramming. It’s also a great source of …

C语言——深入理解指针(4)

目录 1.回调函数 2. qsort 函数的使用 2.1 排序整型数据 2.2 排序结构体数据 3. qsort 函数的模拟实现 1.回调函数 回调函数就是通过一个函数指针调用的函数。 你把函数的地址作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;被调…

【web安全】ssrf漏洞的原理与使用

前言 菜某对ssrf漏洞的总结。 ssrf的作用 主要作用&#xff1a;访问外界无法访问的内网进行信息收集。 1.进行端口扫描&#xff0c;资源访问 2.指纹信息识别&#xff0c;访问相应的默认文件 3.利用漏洞或者和payload进一步运行其他程序 4.get类型漏洞利用&#xff0c;传参数…

用CHAT 写一份销售人员激励方案

问CHAT &#xff1a;写一份销售人员早会激励方案 CHAT回复&#xff1a; 标题&#xff1a;鼓舞斗志&#xff0c;迎接新的一天 -- 销售人员早会激励方案 一、会议的氛围设定&#xff1a; 深呼吸&#xff0c;准备开始一天的事业&#xff1a;清晨的阳光&#xff0c;温暖而明亮&…

Nat. Rev. Chem. | 一份关于用机器学习研究化学问题的评估指导

今天为大家介绍的是来自Tiago Rodrigues团队的一篇论文。机器学习&#xff08;ML&#xff09;有望解决化学领域的重大挑战。尽管ML工作流程的适用性极广&#xff0c;但人们通常发现评估研究设计多种多样。目前评估技术和指标的异质性导致难以&#xff08;或不可能&#xff09;比…

Android BT HCI分析简介

对于蓝牙开发者来说&#xff0c;通过HCI log可以帮助我们更好地分析问题&#xff0c;理解蓝牙协议&#xff0c;就好像网络开发一定要会使用Wireshark分析网络协议一样。 本篇主要介绍HCI log的作用、如何抓取一份HCI log&#xff0c;并结合一个实际的例子来说明如何分析HCI log…

亚马逊云科技 re:Invent 2023:科技前沿风向标,探索未来云计算之窗

文章目录 一、前言二、什么是亚马逊云科技 re:Invent&#xff1f;三、亚马逊云科技 re:Invent 2023 将于何时何地举行四、亚马逊云科技 re:Invent 2023 有什么内容&#xff1f;4.1 亚马逊云科技 re:Invent 2023 主题演讲4.2 亚马逊云科技行业专家探实战 五、更多亚马逊云科技活…

单片机----汇编语言入门知识点

目录 汇编语句的格式 汇编语句的两个基本语句 子程序的调用 查表程序设计 1.x和y均为单字节数的查表程序设计 2.x为单字节数y为双字节数的查表程序设计 3.x和y均为双字节数的查表程序设计 分支转移程序设计 1.单分支选择结构 2.多分支选择结构 循环程序设计 (1) 计…

华为1+x网络系统建设与运维(中级)-练习题2

一.设备命令 LSW1 [Huawei]sys LSW1 同理可得&#xff0c;给所有设备改名 二.VLAN LSW1 [LSW1]vlan ba 10 20 [LSW1]int g0/0/1 [LSW1-GigabitEthernet0/0/1]port link-type trunk [LSW1-GigabitEthernet0/0/1]port trunk allow-pass vlan 10 20 [LSW1-GigabitEthernet0/0/1]in…

根目录/ 空间不够,扩容,导致web页面无法加载问题

现象就是&#xff1a;搭建的web页面无反应&#xff0c;也没报错&#xff0c;怀疑是内存空间不够导致的。/ 扩容步骤如下&#xff1a; 虚拟机为关机状态添加虚拟磁盘 #查看磁盘&#xff0c;并创建新分区 fdisk -l fdisk /dev/sdb p       查看已分区数量&#xff08;我看…

SQL Server 数据库,为products表添加数据

在插入数据的时候&#xff0c;需要注意以下事项。 > 每次插入一整行数据&#xff0c;不可能只插入半行或几列数据。 > 数据值的数目必须与列数相同&#xff0c;每个数据值的数据类型、精度和小数位数也必须与相应的 列匹配。 > INSERT语句不能为标识列指定值&#…

触控板绘画工具Inklet mac功能介绍

Inklet mac是一款触控板绘画工具&#xff0c;把你的触控板变成画画的板子&#xff0c;意思是&#xff0c;你点在触控板的哪里&#xff0c;鼠标就会出现载相应的地方。例如&#xff0c;但你把手指移动到触控盘左下角&#xff0c;那么鼠标也会出现在左下角&#xff0c;对于用户而…

虽有局限性,但在Windows 11上运行Android应用程序是一个不错的新功能

在Windows 11上,Android的Windows子系统(WSA)是一个集成,允许你在笔记本电脑或台式机上与Windows应用程序一起运行Android应用程序,在本指南中,我将向你展示入门步骤。官方规定,你只能从亚马逊应用商店安装应用程序,但也可以使用安卓调试桥(ADB)工具侧载安卓应用程序…

CAPL语言 自动化测试

CAPL语言 自动化测试 CAPL&#xff08;CAN Access Programming Language&#xff09;是一种专为CAN&#xff08;Controller Area Network&#xff09;网络开发的编程语言。这种语言主要用于汽车行业&#xff0c;尤其是在自动化测试和网络通信方面。以下是关于其在自动化测试中…

VSCode主题自定义

记录vscode主题配置 {"editor.minimap.enabled": true,"files.autoSave": "afterDelay","security.workspace.trust.untrustedFiles": "open","markdown-preview-enhanced.previewTheme": "atom-light.css&…

SQL-分页查询offset的用法

今天在做一道关于查询一张表中第二高工资的问题时发现没有思路&#xff0c;经过一番搜索发现需要用到offset偏移量来解决这个问题。 OFFSET关键字用于指定从结果集的哪一行开始返回数据。通常&#xff0c;它与LIMIT一起使用&#xff0c;以实现分页效果。其语法如下&#xff1a…

【mysql】mysgld.log文件太大怎么办

我们有一台测试服务器。跑着一个msyq&#xff0c;发现没有空间了。差看日志文件占用了很多。 怎么破 使用下面命令 echo "" >mysqld.log 执行命令后

Spring Boot统一异常处理 Spring拦截器

小编在前文中向大家描述了Spring AOP的相关内容&#xff1a;Spring AOP-CSDN博客感兴趣的各位老铁可查看一下&#xff01;&#xff01; 那么&#xff0c;我们本文主要是代理搭建来实现一个Spring Boot统一功能处理模块了&#xff0c;当然&#xff0c;这个也是Spring AOP的实战环…