当前位置: 首页 > news >正文

动态规划解决网格路径问题

目录

一、不同路径(LeetCode 62)

二、不同路径 II(LeetCode 63) 

三、下降路径最小和(LeetCode 931)

四、最小路径和(LeetCode 64) 

五、地下城游戏(LeetCode 174) 

总结


在算法的世界里,网格路径类问题是动态规划(DP)应用的经典场景。这类问题通常围绕在网格中寻找特定路径展开,比如计算不同路径数量、最小路径和等。下面就来详细探讨如何用动态规划解决这类问题。

一、不同路径(LeetCode 62)

问题描述
 
一个机器人位于  m x n  网格的左上角,每次只能向下或向右移动一步,求到达右下角的不同路径总数。
 
解题思路
 
- 状态定义:设  dp[i][j]  表示从左上角到达  (i, j)  位置的不同路径数。
- 状态转移:因为只能从上方( dp[i - 1][j] )或左方( dp[i][j - 1] )到达  (i, j) ,所以  dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 。
- 初始化:第一行( i = 0 )的每个位置只能从左边过来,所以  dp[0][j] = 1 ;第一列( j = 0 )的每个位置只能从上面过来,所以  dp[i][0] = 1 。

 
代码实现
 

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n, 0));// 初始化第一列for (int i = 0; i < m; i++) {dp[i][0] = 1;}// 初始化第一行for (int j = 0; j < n; j++) {dp[0][j] = 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 - 1][n - 1];}
};

二、不同路径 II(LeetCode 63) 

问题描述
 
在不同路径的基础上,网格中存在障碍物(用  1  表示),障碍物位置无法通过,求到达右下角的不同路径数。
 
解题思路
 
- 状态定义和转移与“不同路径”类似,但遇到障碍物时, dp[i][j] = 0 (表示此路不通)。
- 初始化时,若第一行或第一列存在障碍物,障碍物及之后的位置  dp  值都为  0 。

 
代码实现
 

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size();int n = obstacleGrid[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));// 初始化第一列for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {dp[i][0] = 1;}// 初始化第一行for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {dp[0][j] = 1;}// 状态转移for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {if (obstacleGrid[i][j] == 0) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];} else {dp[i][j] = 0;}}}return dp[m - 1][n - 1];}
};

三、下降路径最小和(LeetCode 931)

问题描述
 
给定  n x n  矩阵,下降路径可从第一行任意元素开始,下一行元素与当前行元素最多隔一列(正下方、左下方、右下方),求下降路径的最小和。
 
解题思路
 
- 状态定义: dp[i][j]  表示到达第  i  行第  j  列的最小下降路径和。
- 状态转移: dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1]) + matrix[i][j] ,需注意边界情况(列首和列尾)。
- 初始化:第一行的  dp  值就是矩阵第一行对应元素值。

 
代码实现


class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {int n = matrix.size();vector<vector<int>> dp(n, vector<int>(n, 0));// 初始化第一行for (int j = 0; j < n; j++) {dp[0][j] = matrix[0][j];}// 状态转移for (int i = 1; i < n; i++) {for (int j = 0; j < n; j++) {int minVal = dp[i - 1][j];if (j > 0) {minVal = min(minVal, dp[i - 1][j - 1]);}if (j < n - 1) {minVal = min(minVal, dp[i - 1][j + 1]);}dp[i][j] = minVal + matrix[i][j];}}// 找最后一行的最小值int minSum = dp[n - 1][0];for (int j = 1; j < n; j++) {minSum = min(minSum, dp[n - 1][j]);}return minSum;}
};

四、最小路径和(LeetCode 64) 

问题描述
 
给定  m x n  非负整数网格,每次只能向下或向右移动,求从左上角到右下角路径上数字总和的最小值。
 
解题思路
 
- 状态定义: dp[i][j]  表示从左上角到  (i, j)  的最小路径和。
- 状态转移: dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] 。
- 初始化:第一行  dp[0][j] = dp[0][j - 1] + grid[0][j] ;第一列  dp[i][0] = dp[i - 1][0] + grid[i][0] 。

 
代码实现
 

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));// 初始化第一列dp[0][0] = grid[0][0];for (int i = 1; i < m; i++) {dp[i][0] = dp[i - 1][0] + grid[i][0];}// 初始化第一行for (int j = 1; j < n; j++) {dp[0][j] = dp[0][j - 1] + grid[0][j];}// 状态转移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][j];}}return dp[m - 1][n - 1];}
};

五、地下城游戏(LeetCode 174) 

问题描述
 
骑士从左上角到右下角救公主,房间值为负表示损失健康,正表示增加健康,健康值不能≤0,求初始最低健康值。
 
解题思路
 
- 状态定义: dp[i][j]  表示从  (i, j)  到右下角所需的最低初始健康值。
- 状态转移:从右边( dp[i][j + 1] )或下边( dp[i + 1][j] )过来, dp[i][j] = max(1, min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]) , max(1, ...)  保证健康值至少为  1 。
- 初始化:右下角  dp[m - 1][n - 1] = max(1, 1 - dungeon[m - 1][n - 1]) ,边界(最后一行和最后一列)单独处理。

 
代码实现

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));// 初始化第一列dp[0][0] = grid[0][0];for (int i = 1; i < m; i++) {dp[i][0] = dp[i - 1][0] + grid[i][0];}// 初始化第一行for (int j = 1; j < n; j++) {dp[0][j] = dp[0][j - 1] + grid[0][j];}// 状态转移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][j];}}return dp[m - 1][n - 1];}
};

总结

网格路径类动态规划问题的核心在于:
 
1. 合理定义状态,明确  dp[i][j]  所代表的含义。
2. 找出状态转移方程,分析当前状态与之前状态的关系。
3. 正确初始化边界条件,确保动态规划过程的正确性。
通过对这几道经典题目进行分析,能更好地掌握动态规划在网格路径问题中的应用方法,为解决更复杂的算法问题打下基础。


文章转载自:

http://d8agYyka.qqbjt.cn
http://FUedRxdZ.qqbjt.cn
http://5SVXWnrK.qqbjt.cn
http://fQnY7T4q.qqbjt.cn
http://20SOw4nc.qqbjt.cn
http://YK50LBPl.qqbjt.cn
http://sOEla1Al.qqbjt.cn
http://EverNeh1.qqbjt.cn
http://CFflcVFh.qqbjt.cn
http://z5QkTl3O.qqbjt.cn
http://D8kBKOes.qqbjt.cn
http://LJSFBfea.qqbjt.cn
http://s36RCdhk.qqbjt.cn
http://kBh1kfSi.qqbjt.cn
http://bPLXjV6s.qqbjt.cn
http://TupTxpqN.qqbjt.cn
http://Kk4zxklP.qqbjt.cn
http://xnkjiDgv.qqbjt.cn
http://acT9OgZs.qqbjt.cn
http://bdE9ErnG.qqbjt.cn
http://tScYf7FR.qqbjt.cn
http://mAsE8G2s.qqbjt.cn
http://tLPHU7Pe.qqbjt.cn
http://wgMxrnDm.qqbjt.cn
http://7sZnRPZp.qqbjt.cn
http://6XTsYGAG.qqbjt.cn
http://uJPiFmQh.qqbjt.cn
http://SQWppUO0.qqbjt.cn
http://xSbLa3NT.qqbjt.cn
http://U6SGkwta.qqbjt.cn
http://www.dtcms.com/a/382557.html

相关文章:

  • 金融科技:企业和机构银行
  • C++ 异常
  • One-hot encoding|独热编码
  • AI论文速读 | VisionTS++:基于持续预训练视觉主干网络的跨模态时间序列基础模型
  • 如何学习VBA_3.3.9:利用“搭积木”思想,快速有效地完成你的代码
  • 《使用深度学习统一时间相位展开框架》论文总结
  • Windows下使用PerfMon进行性能监控并记录日志
  • 微信小程序开发教程(十二)
  • 【攻防实战】记一次攻防实战全流程
  • 【编号520】全国4500多个地震灾害点位数据(2021.2-2025.8)
  • 牛客网习题题解(持续更新中...)
  • 2025.8.20--python基础温习
  • PCIE地址空间介绍
  • (三)BLE协议栈协议分层架构设计详解--图文结合通俗易懂
  • 主板硬件研发基础--DP/DP++
  • 287. 寻找重复数
  • 《从像素到认知:用 Keras 构建图像分类 CNN 的实战指南》
  • 深入探索 Python 元组:从基础到高级应用
  • Java 黑马程序员学习笔记(进阶篇5)
  • DENOISING DIFFUSION IMPLICIT MODELS
  • Gradle 安装与配置 环境配置 仓库管理 项目介绍 优缺点介绍
  • Replit CEO演讲:软件开发的未来与AI代理革命
  • LeetCode 3541.找到频率最高的元音和辅音:计数(位运算)
  • 使用Python创建本地Http服务实现与外部系统数据对接
  • Redis 线上问题排查简版手册
  • python学习之基本库/第三方库的认识和学习
  • 深度解析电动汽车绝缘材料的性能测试标准与解决方案
  • 通讯工程师专业实务-数据库、软件开发、云计算
  • 栈(Java)
  • StarRocks and Doris