【动态规划篇】- 路径问题

news2025/4/1 4:32:05

在这里插入图片描述

62. 不同路径

题目链接: 62. 不同路径在这里插入图片描述
在这里插入图片描述


题目解析:

  1. 状态表示
    dp[i][j]表示:以[i][j]为终点时,一共有多少种路径。

  2. 状态转移方程
    [i][j]最近的几步来分析问题,要么从[i-1][j]位置向下走一步到达[i][j],要么从[i][j-1]向右走一步到达[i][j]
    所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

  3. 初始化
    为了防止越界,我们就需要初始化下图中红色线画的这部分
    在这里插入图片描述
    这里我们有个小技巧,那就是让dp表多开一行和一列
    在这里插入图片描述
    因为到达[1][1]这个位置共有一种路径,所以我们仅需将dp[1][0]或者dp[0][1]位置初始化为1,其余位置初始化为0即可。

  4. 填表顺序
    从上向下,从左向右

  5. 返回值
    因为dp[i][j]表示到达[i][j]位置时,一共的路径数,我们最终要到达[m][n]位置,所以我们返回dp[m][n]即可。

代码实现:

class Solution {
public:
    int uniquePaths(int m, int n) {
        //1.创建dp表
        //2.初始化
        //3.填表
        //4.返回结果
        vector<vector<int>> dp(m + 1,vector<int>(n + 1));
        dp[1][0] = 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];
    }
};

时间复杂度:O(m*n)
空间复杂度:O(m*n)


63. 不同路径II

题目链接: 63. 不同路径II
在这里插入图片描述
在这里插入图片描述


题目解析:
这道题和上面那道题极度的相似,只不过是加了个障碍物

  1. 状态表示
    dp[i][j]表示:以[i][j]为终点时,一共有多少种路径。

  2. 状态转移方程
    以距离[i][j]最近的一步来划分问题,划分为[i][j]上一步有障碍物时和没有障碍物时。当有障碍物时那么此时的路径就到达不了[i][j],所以到达[i][j]的总的方法数就为0,当没有障碍物时,此时的问题就和上面那道题的思路就一摸一样了要么从[i-1][j]位置向下走一步到达[i][j],要么从[i][j-1]向右走一步到达[i][j]。所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

  3. 初始化
    因为到达[1][1]这个位置共有一种路径,所以我们仅需将dp[1][0]或者dp[0][1]位置初始化为1,其余位置初始化为0即可。

  4. 填表顺序
    从上向下,从左向右

  5. 返回值
    因为dp[i][j]表示到达[i][j]位置时,一共的路径数,我们最终要到达[m][n]位置,所以我们返回dp[m][n]即可。

代码实现:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& ob) {
        //1. 创建dp表   
        //2. 初始化
        //3. 填表
        //4. 返回结果
        int m = ob.size(),n = ob[0].size();
        vector<vector<int>> dp(m + 1,vector<int> (n + 1));
        dp[0][1] = 1;
        for(int i = 1;i <= m;i++)
            for(int j = 1;j <= n;j++)
                if(ob[i - 1][j - 1] == 0) //这里需要特别注意一下下标的映射关系
                     dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

        return dp[m][n];
    }
};

时间复杂度:O(m*n)
空间复杂度:O(m*n)


LCR 166. 珠宝的最高价值

题目链接: LCR 166. 珠宝的最高价值
在这里插入图片描述
题目解析:

  1. 状态表示
    dp[i][j]表示:以[i][j]为终点时,获得的珠宝的最高价值
  2. 状态转移方程
    以最近的一步来划分问题,要么从[i-1][j]位置走一步到达[i][j],要么从[i-1][j]位置走一步到达[i][j],此时珠宝的最高价值就是dp[i-1][j]dp[i][j-1]两者大的一个加上[i][j]位置珠宝的价值。所以dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + frame[i][j]这里要注意下标的映射关系,所以此时的frame[i][j]应该是frame[i-1][j-1],因为数组整体向右下角移动了一位。
  3. 初始化
    这道题我们申请dp表时也多开出一行和一列,为了不影响其余位置的值,我们将这一行和这一列初始化成0即可。
  4. 填表顺序
    从上往下,自左向右
  5. 返回值
    因为dp[i][j]表示以[i][j]为终点时,获得的珠宝的最高价值,我们最终要到达右下角,记二维数组的宽为m宽为n,所以返回dp[m][n]

代码实现:

class Solution {
public:
    int jewelleryValue(vector<vector<int>>& frame) {
        int m = frame.size(),n = frame[0].size();
        //1.创建dp表
        vector<vector<int>> dp(m + 1 ,vector<int> (n + 1));
        //2.初始化
        //因为vector创建的数组默认初始化为0,所以这里不用做处理
        //3.填表
        for(int i = 1;i <= m;i++)
            for(int j = 1;j <= n;j++)
                dp[i][j] = max(dp[i][j-1],dp[i-1][j]) + frame[i-1][j-1];
        return dp[m][n];
    }
};

时间复杂度:O(m*n)
空间复杂度:O(m*n)


931. 下降路径最小和

题目链接: 931. 下降路径最小和
在这里插入图片描述
在这里插入图片描述
题目解析:

  1. 状态表示
    dp[i][j]表示:到达[i][j]位置时的最小下降路径
  2. 状态转移方程
    以最近的一步来划分问题
    在这里插入图片描述
    要到达[i][j]位置,要么从1位置到达[i][j],要么从2位置到达[i][j],要么从3位置到达[i][j]
    在这里插入图片描述
    dp[i][j] = min(dp[i-1][j-1],min(do[i-1][j],dp[i-1][j+1])) + matrix[i][j]
  3. 初始化
    为了保证填表的时候不越界,所以我们在创建dp表的时候多开一行,多开两列。
    为了保证虚拟节点里面的值不影响填表,所以我们在初始化的时候将dp表里面的值都初始化为+∞,将第一行初始化为0即可。
    在这里插入图片描述
  4. 填表顺序
    从上往下
  5. 返回值
    由于最后要求的是下降路径的和最小,dp[i][j]表示的是到达[i][j]位置时的和最小,所以我们返回最后一行的最小值即可

代码实现:

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        //1.创建dp表
        int n = matrix.size();
        vector<vector<int>> dp(n+1,vector<int>(n + 2,INT_MAX));
        //2.初始化
        for(int i = 0;i <= n;i++) dp[0][i] = 0;
        //3.填表
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
                dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i-1][j+1])) + matrix[i-1][j-1];

        int ret = INT_MAX;
        for(int i = 0;i <= n;i++) ret = min(ret,dp[n][i]);
        return ret;
                
    }
};

时间复杂度:O(n²)
空间复杂度:O(n²)


64. 最小路径和

题目链接: 64. 最小路径和
在这里插入图片描述
在这里插入图片描述
题目解析:

  1. 状态表示
    dp[i][j]表示:到达[i][j]位置时的数字最小和
  2. 状态转移方程
    以最近的一步来分析问题,到达[i][j]位置,要么从[i][j-1]位置向右走一步到达[i][j],要么从[i-1][j]位置向下走一步到达[i][j]。要求到达[i][j]位置数字最小和只需求得到达[i][j-1]位置数字最小和在加上[i][j]位置上的数字与[i-1][j]位置数字最小和在加上[i][j]位置上的数字的小的那一个。
    所以dp[i][j] = min(dp[i][j-1],dp[i-1][j]) + grid[i][j]
    🔖这里应注意下标的映射关系,因为下面初始化时我们多开了一行和一列,相当于网格整体向右下角挪了一位,所以最后加的应是grid[i-1][j-1]
  3. 初始化
    下图蓝色圆圈标出的地方会用到绿色方框处的值,此时会产生越界,为了防止越界,所以我们创建dp表的时候多开一行和一列
    在这里插入图片描述
    因为我们要求的是上边和左边小的那一个,所以我们在初始化dp表的时候初始化为+∞,将dp[0][1]或者dp[1][0]初始化为0即可
  4. 填表顺序
    从上往下,从左往右
  5. 返回值
    因为要求的是到达终点时路径上的数字的和最小,dp[i][j]表示到达[i][j]位置是的数字最小值,最后返回最后位置的值即可

代码实现:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        //1.创建dp表
        int m = grid.size(),n = grid[0].size();
        vector<vector<int>> dp(m + 1,vector<int> (n + 1));
        //2.初始化
        for(int i = 2;i <= n ;i++) dp[0][i] = INT_MAX;
        for(int j = 2;j <= m ;j++) dp[j][0] = INT_MAX;
        //3.填表
        for(int i = 1;i <= m;i++)
            for(int j = 1;j <= n;j++)
                dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + grid[i-1][j-1];
        
        return dp[m][n];
    }
};

时间复杂度:O(m*n)
空间复杂度:O(m*n)


174. 地下城游戏

题目链接: 174. 地下城游戏
在这里插入图片描述
在这里插入图片描述
题目解析:

  1. 状态表示
    我们的状态表示方法有两种
    ①以某个位置为结尾
    ②以某个位置为起点
    这道题当我们尝试以某个位置为结尾考虑问题的时候,我们会发现我们还需要知道这个位置的下一个值,那么以某个位置为结尾来表示这道题是不行的。
    所以我们就以[i][j]位置为起点定义状态表示
    dp[i][j]表示:以[i][j]位置为起点到达终点时,所需要的最低初始健康点数

  2. 状态转移方程
    我们以[i][j]位置为起点,必须满足dp[i][j]+dungeon[i][j]≥1,然后要么向右走一步,要么向下走一步,向右走一步必须满足dp[i][j]+dungeon[i][j]≥dp[i][j+1],向下走一步必须满足dp[i][j]+dungeon[i][j]≥dp[i+1][j],所以dp[i][j]≥dp[i][j+1]-dungeon[i][j] 或者dp[i][j]≥dp[i+1][j]-dungeon[i][j] ,因为要求的是dp[i][j]的最小值,最后取等即可 ,由于要求的是到达终点时的最低健康点数,所以我们最后取两者中小的一个。
    这里还需要考虑到一个小细节,dungeon是一个超级大的血包,这里一减dp[i][j]可能为负数,因为dp[i][j]必须是大于等于1的,所以我们最后还要处理一下。
    在这里插入图片描述

  3. 初始化
    如图所示绿色三角形的位置会越界,为了防止越界,我们在创建dp表时多开一行多开一列,因为要求的时右一步和下一步两者的最小值,所以我们初始化dp表是初始化为最大(INT_MAX),因为dp[i][j]表示以[i][j]位置为起点到达终点时需要的最低初始健康点数,最终救出公主时的健康点数应该为1,所以我们将最后两个位置的值初始化为1即可。

  4. 填表顺序
    从上往下填每一行,每一行从右往左

  5. 返回值
    因为我们从[0][0]位置为起点,所以我们最后返回dp[0][0]即可。

代码实现:

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        ///1.创建dp表
        int m = dungeon.size(),n = dungeon[0].size();
        vector<vector<int>> dp(m + 1,vector<int> (n + 1,INT_MAX));
        //2.初始化
        dp[m][n-1] = dp[m-1][n] = 1;
        //3.填表
        for(int i = m-1;i >= 0 ;i--)
        {
            for(int j = n-1;j >= 0 ;j--)
            {
                dp[i][j] = min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j];
                dp[i][j] = max(1,dp[i][j]);
            }
        }
        return dp[0][0];
    }
};

时间复杂度:O(m*n)
空间复杂度:O(m*n)


👍 如果对你有帮助,欢迎:

  • 点赞 ⭐️
  • 收藏 📌
  • 关注 🔔

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

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

相关文章

《新凯来:半导体设备制造领域的“国家队”》

《新凯来&#xff1a;半导体设备制造领域的“国家队”》 一、SEMICON China 爆火出圈&#xff1a;31 款设备背后的 “深圳力量” 1.1 展会现象级热度 在 2025 年 SEMICON China 展会现场&#xff0c;新凯来展台成了整届展会当之无愧的 “顶流”&#xff0c;被来自全球各地的专…

AI大模型最新发布[update@202503]

OpenAI GPT-4o&#xff1a;多模态&#xff0c;“o”代表Omni&#xff0c;即全能的意思&#xff0c;凸显了其多功能的特性。 多模态交互&#xff0c;GPT-4o可以接受文本、音频和图像的任意组合作为输入&#xff0c;并生成文本、音频和图像的任意组合输出。实时推理能力&#x…

深入浅出 Embedding

1. 什么是 Embedding? Embedding(嵌入)是一种将高维数据映射到低维连续空间的技术,用于表达数据的语义关系。简单来说,它是一种向量化表示,将文本、图像、用户行为等信息转换为数值向量,使得相似的数据在向量空间中距离更近。 2. 如何理解 Embedding? 2.1 浅显易懂的…

java项目之基于ssm的乡镇自来水收费系统(源码+文档)

项目简介 乡镇自来水收费系统实现了以下功能&#xff1a; 乡镇自来水收费系统在Eclipse环境中&#xff0c;使用Java语言进行编码&#xff0c;使用Mysql创建数据表保存本系统产生的数据。系统可以提供信息显示和相应服务&#xff0c;其管理员管理水表&#xff0c;审核用户更换…

Spring AI MCP 架构详解

Spring AI MCP 架构详解 1.什么是MCP? MCP 是一种开放协议&#xff0c;它对应用程序向大语言模型&#xff08;LLMs&#xff09;提供上下文信息的方式进行了标准化。可以把 MCP 想象成人工智能应用程序的 USB-C 接口。就像 USB-C 为将设备连接到各种外围设备和配件提供了一种…

目标识别与双目测距(1)环境搭建:Ubuntu+yolov5+pcl库

环境情况 ubuntu 18.04 → 20.04&#xff08;最终&#xff09; 安装Ubuntu1804虚拟机系统 Anaconda&#xff1a;可参考我的另一篇文章 Python 3.6.13 → 3.8&#xff08;最终&#xff09;Anaconda3-2021.05 目标识别&#xff1a;YOLOv5相关 1、安装git sudo apt install gi…

OpenAI API - Agent

文章目录 代理概述模型工具知识与记忆防护栏编排入门 语音代理选择正确的架构语音到语音&#xff08;多模态&#xff09;架构链式架构 构建语音代理使用语音到语音架构进行实时处理将音频输入链接到文本处理 → 音频输出 代理 了解如何使用 OpenAI API 构建代理。 https://pl…

Strawberry perl的下载,查询版本号,配置Path环境变量,查找perl解释器的位置

Strawberry Perl 是一个适用于 Microsoft Windows 的 Perl 环境&#xff0c;包含运行和开发 Perl 应用程序所需的一切。它旨在尽可能接近 UNIX 系统上的 Perl 环境。 下载 官网: Strawberry Perl for Windows - Releases 各个版本: Strawberry Perl for Windows - Releases …

MySQL的基础语法2(函数-字符串函数、数值函数、日期函数和流程函数 )

目录 一、字符串函数 1.常见字符串函数 ​编辑 2.字符串函数的基本使用 3.字符串函数的数据库案例演示 二、数值函数 1.常见数值函数&#xff08;如下&#xff09;&#xff1a; 2.数值函数的基本使用 3.数值函数的数据库案例演示 三、日期函数 1.常见的日期函数 2.日…

5G_WiFi_CE_杂散测试

目录 一、规范要求 1、法规目录&#xff1a; 2、限值&#xff1a; &#xff08;1&#xff09;带外发射杂散 &#xff08;2&#xff09;带内发射杂散 &#xff08;3&#xff09;接收杂散 二、测试方法 1、带外发射杂散 &#xff08;1&#xff09;测试条件 &#xff08…

大数据Spark(五十五):Spark框架及特点

文章目录 Spark框架及特点 一、Spark框架介绍 二、Spark计算框架具备以下特点 Spark框架及特点 一、Spark框架介绍 Apache Spark 是一个专为大规模数据处理而设计的快速、通用的计算引擎。最初由加州大学伯克利分校的 AMP 实验室&#xff08;Algorithms, Machines, and Pe…

UI产品经理基础(六):如何解决用户的质疑?

在需求调查中遇到用户质疑“不专业”或“不了解需求”&#xff0c;本质上是用户对产品经理的信任缺失或沟通鸿沟导致的。要化解这种质疑&#xff0c;需从专业能力展示、沟通方式优化、用户参与感提升三个维度切入&#xff0c;结合具体场景采取针对性策略。以下是系统化的解决方…

【大数据技术】大数据技术概念及概述

1. 大数据概念 数据 是实时或观察的结果是对客观事务的逻辑归纳是用于表示客观事物的未经加工的原始素材 数据的产生 对客观事务的计量和记录尝试的数据 单位换算1 byte8 bit1 k1024 byte1 mb1024 k1 g1024 m1 t1024 g1 p1024 t1 e1024 p1 z1024 e1 y1024 z1 b1024 y1 n10…

Python库()

1.概念 Matplotlib 库&#xff1a;是一款用于数据可视化的 Python 软件包&#xff0c;支持跨平台运行&#xff0c;它能够根据 NumPy ndarray 数组来绘制 2D 图像&#xff0c;它使用简单、代码清晰易懂 Matplotlib 图形组成&#xff1a; Figure&#xff1a;指整个图形&#xf…

AI知识补全(八):多模态大模型是什么?

名人说&#xff1a;人生如逆旅&#xff0c;我亦是行人。 ——苏轼《临江仙送钱穆父》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;AI知识补全&#xff08;七&#xff09;&#xff1a;AI Agent 智能…

Docker-MySQL安装-命令解读-常见命令-数据卷挂载-本地目录挂载-自定义镜像-网络-前端部署-DockerCompose

目录 Docker&#xff1a; 安装MySQL&#xff1a; 镜像容器&#xff1a; 镜像仓库&#xff1a; ​编辑命令解读&#xff1a; 镜像命名规范&#xff1a; docker run中常见参数&#xff1a; Docker常见命令&#xff1a; ​编辑数据卷&#xff1a; ​编辑数据卷-操作命令&…

Docker 安装部署Harbor 私有仓库

Docker 安装部署Harbor 私有仓库 系统环境:redhat x86_64 一、首先部署docker 环境 定制软件源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repoyum install -y yum-utils device-mapper-persistent-data lvm2…

StarRocks 存算分离在京东物流的落地实践

康琪&#xff1a;京东物流高级技术专家、StarRocks & Apache Flink Contributor 导读&#xff1a;本文整理自京东物流高级技术专家在 StarRocks 年度峰会上的分享&#xff0c;UData 平台从存算一体到存算分离架构演进后&#xff0c;查询性能得到提升。Cache hit 时&#xf…

英伟达GB300新宠:新型LPDDR5X SOCAMM内存

随着人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和高性能计算&#xff08;HPC&#xff09;应用的快速发展&#xff0c;对于高效能、大容量且低延迟内存的需求日益增长。NVIDIA在其GB系列GPU中引入了不同的内存模块设计&#xff0c;以满足这些严格…