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

news2024/12/25 9:17:06

在这里插入图片描述

君兮_的个人主页

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

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.coloradmin.cn/o/1277613.html

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

相关文章

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

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

在cmd下查看mysql表的结构信息

我提前已经在mysql数据库中创建了一个表&#xff1a; 在cmd下&#xff0c;登录mysql以后&#xff0c;使用命令describe 表名、或者explain 表名可以查看表结构信息。但在实践中&#xff0c;查看表结构&#xff0c;多用describe命令&#xff0c;而查看执行计划用explain。 例…

FreeRtos第一个task是怎么run起来的

第一个task是怎么起来的呢&#xff1f;分析完vTaskStartScheduler&#xff0c;就会有答案了。 那vTaskStartScheduler()干了啥呢&#xff1f; 一、创建prvIdleTask task 二、xTimerCreateTimerTask里创建prvTimerTask task 三、初始化一些全局变量 3.1 xNextTaskUnblockTime…

计算机组成学习-数据的表示和运算总结

1、进制与编码 1.1 进位计数法 常用的进位计数法有十进制、二进制、八进制、十六进制等。十六进制每个 数位可取0〜9、A、B、C、D、E、F中的任意一个&#xff0c;其中A、B、C、D、E、F分别表示 10〜15。 八进制数字通常以前缀 "0"&#xff08;零&#xff09;加上数…

前端文本省略号后面添加复制文字

前端文本省略号后面添加复制文字 1、效果图 2、代码展示 <div class"link-content-wrap" click"copyLinkText"><div class"link-content">{{ shareResult.url || }} </div><span class"show-ellipsis" click&…

「C++」哈希表的实现(unordered系底层)

&#x1f4bb;文章目录 &#x1f4c4;前言哈希表概念哈希函数 哈希冲突闭散列开散列 &#x1f4d3;总结 &#x1f4c4;前言 unordered系列的关联式容器之所以效率比较高,是因为其底层使用了哈希结构&#xff0c;使其在查找上的时间复杂度几乎减低到了 O ( 1 ) O(1) O(1)。 哈希…

微信扫码登录的两种方式:利用微信开放平台、利用微信公众平台(微信公众号)

微信扫码登录&#xff0c;有两种实现方式&#xff1a; 方式1、微信开放平台是微信为了接入更多第三方应用而开放的接口&#xff0c;依赖公司在【微信开放平台】用【公司营业执照】注册的账号&#xff0c;才能实现扫码登录 方式2、微信公众平台是扫码通过微信公众号授权登录的&a…

2023 如何下载最干净的 win10 win11 微软官方原版系统镜像(详细图文)

前言 不会吧不会吧&#xff0c;不会到现在还有人不会下载原版系统镜像吧 开始 win10官方下载工具下载地址&#xff1a;https://www.microsoft.com/zh-cn/software-download/windows10 win11官方下载工具下载地址&#xff1a;https://www.microsoft.com/zh-cn/software-downl…

Asp.net core WebApi 配置自定义swaggerUI和中文注释,Jwt Bearer配置

1.创建asp.net core webApi项目 默认会引入swagger的Nuget包 <PackageReference Include"Swashbuckle.AspNetCore" Version"6.2.3" />2.配置基本信息和中文注释&#xff08;默认是没有中文注释的&#xff09; 2.1创建一个新的controller using Micr…

基于PLC的采摘机械手系统(论文+源码)

1.系统设计 本次设计围绕基于PLC的采摘机械手系统进行设计&#xff0c; PLC即可编程控制器其是一种常见的微处理器&#xff0c;本次拟采用西门子是S7-200 PLC&#xff0c;一方面对整个设计从器件选型到I/O分配&#xff0c;图纸绘制等进行设计&#xff0c;另一方面还通过组态王…

4/150:寻找两个正序数组的中位数⭐ 5/150最长回文子串

题目&#xff1a;4/150寻找两个正序数组的中位数 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 题解1&#xff1a;暴力 暴力思路简介&#x…

uniapp运行到安卓基座app/img标签不显示

img是html中的标签&#xff0c;他也是一个单标签 image属于服务器控件&#xff0c;是个双标签 问题&#xff1a;uniapp运行到app安卓基座后图片无法显示 原因&#xff1a;自己使用了img标签&#xff0c;而且输入路径无提示&#xff0c;img标签导致图片不显示 解决&#xff…

J-LINK J-FLASH 下载STM32单片机程序使用教程

J-LINK J-FLASH 下载STM32单片机程序使用教程 Chapter1 J-LINK J-FLASH 下载STM32单片机程序使用教程1.安装提供的 JLINK驱动程序2. 点击打开 J-Flash V7.223.点击 create a new project.&#xff08;使用后可以在软件菜单File保存这个烧写工程&#xff0c;后续直接打开使用即可…

一篇带你串通数据结构

文章目录 导论数据结构的定义数据结构在计算机科学中的重要性为什么学习数据结构很重要 1、基本概念1.1、数据、数据元素和数据项的概念1.2、数据对象与数据结构的关系1.3、逻辑结构与物理结构 2、线性结构2.1、数组2.2、链表2.3、栈2.4、队列 3、非线性结构3.1、树3.2、图 4、…

九、FreeRTOS之FreeRTOS列表和列表项

本节需要掌握以下内容&#xff1a; 1&#xff0c;列表和列表项的简介&#xff08;熟悉&#xff09; 2&#xff0c;列表相关API函数介绍&#xff08;掌握&#xff09; 3&#xff0c;列表项的插入和删除实验&#xff08;掌握&#xff09; 4&#xff0c;课堂总结&#xff08;掌…

Windows启动nacos操作文档

Windows启动nacos操作文档 1、新建数据库nacos_config 2、导入nacos\conf\nacos-mysql.sql文件 /******************************************/ /* 数据库全名 nacos_config */ /* 表名称 config_info */ /******************************************/ CREATE T…

JOSEF约瑟时间继电器ARTD-DC110V-2H2D 0.25-2.5s导轨安装

ARTD系列断电延时继电器&#xff1a; ARTD-220VDC-1H1D断电延时继电器&#xff1b;ARTD-220VDC-2H断电延时继电器&#xff1b; ARTD-220VDC-2H2D断电延时继电器&#xff1b;ARTD-220VDC-4H断电延时继电器&#xff1b; ARTD-110VDC-1H1D断电延时继电器&#xff1b;ARTD-110VD…

ssm的“魅力”西安宣传网站(有报告)。Javaee项目。

演示视频&#xff1a; ssm的“魅力”西安宣传网站(有报告)。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring SpringMvc MybatisVueLayuiElemen…

使用调研工具做好问卷调查的方法与策略

提起问卷调查大家应该都不陌生&#xff0c;学校会使用问卷调查收集学生信息或意见、企业使用问卷调查了解市场、深入用户。和其他的调查方式相比&#xff0c;问卷调查更能贴近被调查者真实想法&#xff0c;反馈真实数据。而互联网的崛起也使得大家纷纷从线下问卷转战到线上问卷…

AD7124-4 实测热电偶数据读取,电压精度到稳定到±1uV, 电压波动260nV, 温度精度到±0.01℃

AD7124-4 实测热电偶数据读取&#xff0c;电压精度到稳定到1uV, 电压波动260nV, 温度精度到0.01℃ AD7124_STM32_ADI官网例程使用stm32 和ad7124做温控调试&#xff0c;发现效果还是不错的&#xff0c;至少比ads1256的效果好多啦&#xff01;Chapter1 AD7124-4 实测热电偶数据读…