动态规划之路径问题

路径问题

  • 1. 不同路径(medium)
  • 2. 不同路径II(medium)
  • 3. 礼物最大值(medium)
  • 4. 下降路径最小和(medium)
  • 5. 最⼩路径和(medium)
  • 6. 地下城游戏(hard)

1. 不同路径(medium)

1.题目链接:不同路径
2.题目描述:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
在这里插入图片描述

3.问题分析:
对于动态规划关于路径问题的分析,首先需要选取某个位置,然后以该位置为起点或者结尾进行分析。如这题dp数组中i位置的结果是需要i-1、i-2等位置算出来的,这种情况就以i位置为结尾进行分析。

  1. 状态表示:对于m*n的网格来说,每一个格子可以对应到一个二维数组中的元素,对于从起点到某点(i,j)由多少种不同路径是从起始位置进行计算,所以以(i,j)位置为结尾进行分析。用dp[i][j]表示:从起点位置到[i,j]位置处,一共有多少种方式。有时候是不知道状态表示是正确还是错误的,为此只能先往下分析
  2. 状态转移方程:对(i,j)位置进行分析,dp[i][j]表示从起点位置到[i , j]位置处,一共有多少种方式,那么怎样才能到达 [i , j] 这个位置?因为只能往下或者往右走,所以到达 [i , j] 位置可以是 [i - 1, j] 或者是 [i , j - 1]这两个位置,两个位置的值进行相加 ,就是到达[i , j]位置处总共的方式。因此状态转移方程为:dp[i , j] = dp[i - 1, j] + [i , j - 1]。
  3. 初始化:对于第一行第一列来说,进行-1操作会放生越界情况。可以用if语句判断一下,也可以添加一行一列,多出来的一行一列成为辅助节点,使⽤这种技巧要注意两个点:辅助结点⾥⾯的值要保证后续填表是正确的;下标的映射关系。初始化只将dp[0][1]位置初始化为1即可。
  4. 填表顺序:从上往下填每⼀⾏,在填写每⼀⾏的时候从左往右。
  5. 返回值:返回dp[m][n]。
    在这里插入图片描述

4.代码如下:

class Solution
{
public:int uniquePaths(int m, int n){vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // 创建⼀个 dp表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];}
};

2. 不同路径II(medium)

1.题目链接:不同路径II
2.题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
在这里插入图片描述

3.问题分析
这道题和不同路径I区别就是这道题中的网格有障碍物,所以大致分析思路是相同的,就比如这道题是以[i, j]位置为结尾进行分析,状态表示也相同。

  1. 状态表示:dp[i][j] 表示:⾛到 [i, j] 位置处,⼀共有多少种⽅式。
    以[i, j]位置为结尾进行分析,同上到题,到达 [i , j] 位置可以是 [i - 1, j] 或者是 [i , j - 1]这两个位置,两个位置的值进行相加 ,就是到达[i , j]位置处总共的方式;但是如果有障碍物呢?比如[i - 1, j] 或者是 [i , j - 1]其中有一个是障碍物,那么到达[i , j] 位置的所有方法就是其中一个某个不是障碍物的路径数。所以另一个有障碍的路径数为零,即遇到障碍物就不需要计算这个位置上的值,直接让它等于0。
  2. 状态转移方程:同上一题dp[i , j] = dp[i - 1, j] + [i , j - 1]。不过如果这个位置上有障碍物,那么就不需要计算这个位置上的值,直接让它等于 0 即可。
  3. 初始化:同上一题,可以添加⼀行,并且添加⼀列后,只需将dp[1][0]的位置初始化为1 即可。
  4. 填表顺序:从上往下填每⼀⾏,在填写每⼀⾏的时候从左往右。
  5. 返回值:返回dp[m][n]。

在这里插入图片描述4.代码如下

class Solution 
{
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size(), n = obstacleGrid[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));dp[0][1] = 1;for (int i = 1; i <= m; ++i){for (int j = 1; j <= n; ++j){if (obstacleGrid[i - 1][j - 1] == 0){dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}}return dp[m][n];}
};

3. 礼物最大值(medium)

1.题目链接:礼物最大值
2.题目描述
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
在这里插入图片描述

3.问题分析
这道题和上述两道又有所不同,但都属于同种类型,所以方法大致一样。先进行状态表示:用dp[i][j] 表示:⾛到 [i, j] 位置处,此时的最⼤价值。上述两题是要算出路径数,所以将[i - 1, j] 的路径数与[i , j - 1]的路径数相加。而这道题是要求路径上的最大价值,可以将[i - 1, j] 路径上的价值数与[i , j - 1]路径上的价值数进行比较,保留两个中较大的值然后再加上grid[i,j]位置上的值即可。

  1. dp[i][j] 表⽰:⾛到 [i, j] 位置处,此时的最⼤价值
  2. 状态转移方程:从[i - 1, j] 位置,向下⾛⼀步,此时到达 [i, j] 位置能拿到的礼物价值为 dp[i - 1][j] + grid[i][j] ; 从 [i, j - 1] 位置,向右⾛⼀步,此时到达 [i, j] 位置能拿到的礼物价值为dp[i][j - 1] + grid[i][j]。
  3. 初始化:同上一题,可以添加⼀行,并且添加⼀列后,所有的值都为 0 即可。
  4. 填表顺序:从上往下填每⼀⾏,在填写每⼀⾏的时候从左往右。
  5. 返回值:返回dp[m][n]。

在这里插入图片描述

4.代码如下

class Solution
{
public:int maxValue(vector<vector<int>>& grid){int m = grid.size(), n = grid[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));for (int i = 1; i <= m; i++)for (int j = 1; j <= n; j++)dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];return dp[m][n];}
};

4. 下降路径最小和(medium)

1.题目链接:下降路径最小和
2.题目描述
给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。
下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
在这里插入图片描述
3.问题分析
大致思路不变,先表示状态,用二维数组dp[i][j] 表⽰:到达 [i, j] 位置时,所有下降路径中的最⼩和。然后进行分析,上述所示的问题,因只能向左或向下移动,所以[i,j]的路径数是将[i - 1, j] 的路径数与[i , j - 1]的路径数相加;而这道题位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) ;以[i,j]为结尾进行分析,到达[i,j]位置的上一层应当是[i - 1, j - 1],[i - 1, j],[i - 1, j + 1]中三者最小的一个,然后加上matrix[i,j]的值,然后遍历依次填写dp表即可。其中有越界问题,如[0, j]或[i, n - 1]位置,可以用辅助结点来解决,增加两列,一列在起始,另一列在末尾;最后寻找最后一行最小的值即为下降路径最小和。

  1. dp[i][j] 表⽰:到达 [i, j] 位置时,所有下降路径中的最⼩和。
  2. dp[i][j] = min(dp[i - 1][j], min(dp[i - 1][j - 1], dp[i - 1][j +1])) + matrix[i][j] 。
  3. 初始化:需要加上两列,所有的位置都初始化为⽆穷⼤,将dp表第一行初始为matrix第一行(左右两列的辅助结点是无穷大)
  4. 从上往下填每⼀⾏,在填写每⼀⾏的时候从左往右。
    4.代码如下
class Solution 
{
public:int minFallingPathSum(vector<vector<int>>& matrix) {int n = matrix.size();//初始化dp表,全部初始化为无穷大vector<vector<int>> dp(n, vector<int>(n + 2, INT_MAX));//=将dp表第一行初始为matrix第一行for (int j = 0; j < n; ++j)dp[0][j + 1] = matrix[0][j];//从第二行第二列开始遍历for (int i = 1; i < n; ++i){//在dp表中不是辅助结点的位置范围是1到nfor (int j = 1; j <= n; ++j){int x = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i - 1][j + 1]));dp[i][j] = x + matrix[i][j - 1]; //没有添加行,matrix对应的映射为i,j-1}}//寻找最后一行最小值int ret = dp[n - 1][0];for (int j = 1; j <= n; ++j)ret = min(ret, dp[n - 1][j]);return ret;}
};

5. 最⼩路径和(medium)

1.题目链接:最⼩路径和
2.题目描述
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
在这里插入图片描述

3.问题分析
这道题与上述题基本一致了,分析就略过。

  1. 状态表⽰:dp[i][j] 表⽰:到达 [i, j] 位置处,最⼩路径和是多少。
  2. 这道题是要求路径上的最小和,可以将[i - 1, j] 路径上的最小和与[i , j - 1]路径上的最小和进行比较,保留两个中较小的值然后再加上grid[i,j]位置上的值即可。
  3. 添加⼀⾏,并且添加⼀列后,所有位置的值可以初始化为⽆穷⼤,然后让dp[0][1] = dp[1][0] = 0 即可。
  4. 要返回的结果是dp[m][n]。因为添加了一行一列。
    4.代码如下
class Solution
{
public:int minPathSum(vector<vector<int>>& grid){int m = grid.size(), n = grid[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));dp[0][1] = dp[1][0] = 0;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];}
};

6. 地下城游戏(hard)

1.题目链接:地下城游戏
2.题目描述
恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。
骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。
有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。
为了尽快解救公主,骑士决定每次只 向右 或 向下 移动一步。
返回确保骑士能够拯救到公主所需的最低初始健康点数。
注意:任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。
在这里插入图片描述

3.问题分析
这道题已知骑士到达公主所在地,也就是右下角,骑士此时所剩健康点数为1 ,求到达终点时,起始位置生命健康值的最小点数。所以这道题应该从右下角开始遍历,至于怎么遍历,看如下分析:状态表示:dp[i][j] 表⽰:从 [i, j] 位置出发,到达终点时所需的最低初始健康点数; 以[i,j]位置为起点进行分析,有很多条路径可以到达终点,路径上有加血的,有减血的,我们要求什么?求的是血最多的时候?不是,求的是应该血量刚够过该路径的值 也就是dungeon数组中路径求和过程中各个路径负数的最大值的绝对值,所以减去 dungeon[i][j]就是所需的生命值,如果为dp结果负数,就说明能量值很大,而dp[i][j] 表⽰:从 [i, j] 位置出发,到达终点时所需的最低初始健康点数,dp[i][j]大于0,出现负数就要赋值为1。负数就代表起始位置生命值最低值为负数,这很显然不肯能为负数
位置[i + 1, j]或者 [i, j + 1]可以到达[i, j] 位置,dp的位置表示最低点数,所以选取 [i + 1, j], [i, j + 1]两者中的较小值减去dungeon[i][j]就是dp[i][j]的最小值。

  1. dp[i][j] 表⽰:从 [i, j] 位置出发,到达终点时所需的最低初始健康点数。
  2. 状态转移方程:dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];如果dp[i][j] <= 0,则dp[i][j] = 1。
  3. 初始化:在本题中,在 dp 表最后⾯添加⼀⾏,并且添加⼀列后,所有的值都先初始化为⽆穷⼤,然后让dp[m][n - 1] = dp[m - 1][n] = 1 即可。
  4. 填表顺序:需要从下往上填每⼀⾏,每⼀⾏从右往左。
  5. 返回值:dp[0][0]。
    4.代码如下
class Solution
{
public:int calculateMinimumHP(vector<vector<int>>& dungeon){int m = dungeon.size(), n = dungeon[0].size();// 建表 + 初始化vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));dp[m][n - 1] = dp[m - 1][n] = 1;// 填表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];if (dp[i][j] <= 0){dp[i][j] = 1;}}}// 返回结果return dp[0][0];}
};

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

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

相关文章

图床项目进度(一)——UI首页

1. 前言 前面我不是说了要做一个图床吗&#xff0c;现在在做ui。 我vue水平不够高&#xff0c;大部分参考b站项目照猫画虎。 vue实战后台 我使用ts&#xff0c;vite&#xff0c;vue3进行了重构。 当然&#xff0c;我对这些理解并不深刻&#xff0c;许多代码都是游离于表面&am…

基于决策树(Decision Tree)的乳腺癌诊断

决策树(DecisionTree)学习是以实例为基础的归纳学习算法。算法从--组无序、无规则的事例中推理出决策树表示形式的分类规则,决策树也能表示为多个If-Then规则。一般在决策树中采用“自顶向下、分而治之”的递归方式,将搜索空间分为若千个互不相交的子集,在决策树的内部节点(非叶…

Spring事务和事务传播机制

目录 一. Spring 中事务的实现 1. 编程式事务 2. 声明式事务 3. Transaction 参数的设置 4. Transaction 的隔离级别 5. Transaction 的工作原理 二. Spring 事务传播机制 七种事务传播机制 支持当前事务 不支持当前事务 嵌套事务 一. Spring 中事务的实现 1. 编程式事…

mmdetection基于 PyTorch 的目标检测开源工具箱 入门教程

安装环境 MMDetection 支持在 Linux&#xff0c;Windows 和 macOS 上运行。它需要 Python 3.7 以上&#xff0c;CUDA 9.2 以上和 PyTorch 1.8 及其以上。 1、安装依赖 步骤 0. 从官方网站下载并安装 Miniconda。 步骤 1. 创建并激活一个 conda 环境。 conda create --name…

Docker是什么?详谈它的框架、使用场景、优势

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、什么是 Docker&#xff1f; 二、Docker 的架构 1、Docker客户端 2、Docker守护进程 3、Docker镜像 4、Docker容器 5、Docker…

【业务功能篇76】微服务网关路由predicates断言条件-filters路由转换地址-跨域问题-多级目录树化层级设计-mybatisPlus逻辑删除

业务开发-基础业务-分类管理 启动renren-fast如果出现如下错误 -Djps.track.ap.dependenciesfalse 添加相关配置即可 分类管理 1.后端分类接口 JDK8特性&#xff1a;https://blog.csdn.net/qq_38526573/category_11113126.html 在后端服务中我们需要查询出所有的三级分类信…

汽车摩托车零部件出口管理ERP解决方案

近年来&#xff0c;随着全球经济的发展&#xff0c;人们对交通工具的需求增加&#xff0c;国内汽车、摩托车市场的不断扩大&#xff0c;以及国内制造技术的不断提高&#xff0c;中国汽车、摩托车零部件出口业务迎来了广阔的发展前景&#xff0c;带动了汽车配件和摩托车配件市场…

分布式下的session共享问题

首页我们确定在分布式的情况下session是不能共享的。 1.不同的服务&#xff0c;session不能共享&#xff0c;也就是微服务的情况下 2.同一服务在分布式情况&#xff0c;session同样不能共享&#xff0c;也会是分布式情况 分布式下session共享问题解决方案(域名相同) 1.session复…

IDEA常用插件之类Jar包搜索Maven Search

文章目录 IDEA常用插件之类Jar包搜索Maven Search说明安装插件使用方法1.搜索自己要搜的jar包2.根据类名搜索 IDEA常用插件之类Jar包搜索Maven Search 说明 它可以帮助用户快速查找和浏览Maven中央存储库中可用的依赖项和插件。它可以帮助用户更方便地管理项目依赖项。 安装…

idea 对JavaScript进行debug调试

文章目录 1.新增 JavaScript Debug 配置2.配置访问地址3.访问url. 打断点测试 前言 : 工作中接手别人的前端代码没有注释&#xff0c;看浏览器的network或者console切来切去&#xff0c;很麻烦&#xff0c;可以试试idea自带的javscript debug功能。 1.新增 JavaScript Debug 配…

『SEQ日志』在 .NET中快速集成轻量级的分布式日志平台

&#x1f4e3;读完这篇文章里你能收获到 如何在Docker中部署 SEQ&#xff1a;介绍了如何创建和运行 SEQ 容器&#xff0c;给出了详细的执行操作如何使用 NLog 接入 .NET Core 应用程序的日志&#xff1a;详细介绍了 NLog 和 NLog.Seq 来配置和记录日志的步骤日志记录示例&…

UE4/5Niagara粒子特效之Niagara_Particles官方案例:3.3->4.3

目录 3.3 Visibility Tag 左边的发射器&#xff1a; 发射器更新 粒子生成 粒子更新 右边的发射器 和左边发射器不同的地方 3.4 Texture Sampling 发射器更新 粒子生成 粒子更新 4.1Play Audio Per Particle 系统 第三个发射器 发射器更新 粒子生成 粒子更新 第二个…

1268. 搜索推荐系统

链接&#xff1a; 1268. 搜索推荐系统 题解&#xff1a; class Solution { public: struct Trie {Trie() {end false;next.resize(26, nullptr);}bool end;std::set<std::string> words;std::vector<Trie*> next; };void insert_trie(const std::string& w…

Android相机-HAL子系统

引言 应用框架要通过拍照预览摄像获得照片或者视频,就需要向相机子系统发出请求, 一个请求对应一组结果 一次可发起多个请求&#xff0c;并且提交请求是非阻塞的&#xff0c;始终按照接收的顺序以队列的形式先进先出地进行顺序处理 一个请求包含了拍摄和拍照配置的所有信息&…

【音视频处理】转编码H264 to H265,FFmpeg,代码分享讲解

大家好&#xff0c;欢迎来到停止重构的频道。 本期我们讨论音视频文件转编码&#xff0c;如将视频H264转H265等。 内容中所提及的代码都会放在GitHub&#xff0c;感兴趣的小伙伴可以到GitHub下载。 我们按这样的顺序展开讨论&#xff1a;​ 1、 编码的作用 2、 转编码的…

avue-ueditor中隐藏部分工具栏

项目中不需要那么多工具栏,只需要展示部分工具栏 <avue-ueditor v-model"content" v-bind"options" :customConfig"customConfig" :placeholder"placeholder"></avue-ueditor>//按需隐藏或者显示工具栏即可 props: {custo…

C语言基础之——操作符(上)

本篇文章&#xff0c;我们将展开讲解C语言中的各种常用操作符&#xff0c;帮助大家更容易的解决一些运算类问题。 这里提醒一下小伙伴们&#xff0c;本章知识会大量涉及到二进制序列&#xff0c;不清楚二进制序列的小伙伴&#xff0c;可以去阅读我的另一篇文章《数据在内存中的…

6、Spring_Junit与JdbcTemplate整合

Spring 整合 1.Spring 整合 Junit 1.1新建项目结构 1.2导入依赖 导入 junit 与 Spring 依赖 <!-- 添加 spring 依赖--> <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version…

MySQL 8.0 多实例的配置应用

文章目录 同版本多实例配置部署、启动、连接 不同版本多实例配置初始化initialize-insecure 含义 启动 同版本多实例 配置 mkdir -p /data/330{7..9}/data chown -R mysql.mysql /data/* cat > /data/3307/my.cnf <<EOF [mysqld] usermysql basedir/usr/local/mysql …

Skywalking Kafka Tracing实现

背景 Skywalking默认场景下&#xff0c;Tracing对于消息队列的发送场景&#xff0c;无法将TraceId传递到下游消费者&#xff0c;但对于微服务场景下&#xff0c;是有大量消息队列的业务场景的&#xff0c;这显然无法满足业务预期。 解决方案 Skywalking的官方社区中&#xf…