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

动态规划之路径问题

文章目录

  • 不同路径
  • 不同路径 II
  • 珠宝的最高价值
  • 下降路径最小和
  • 最小路径和
  • 地下城游戏

不同路径

题目:不同路径

在这里插入图片描述
思路

  • 状态表示:dp[i][j]表示走到[i, j]位置时,一共有多少种方式
  • 状态转移方程:到达[i, j]位置有两种方式
    • [i - 1, j][i, j]
    • [i, j - 1][i, j]
    • 所以,状态转移方程为:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
  • 初始化:在 dp数组前添加一行和一列,初始化dp[0][1] = 1
  • 填表顺序:从上往下,从左往右
  • 返回值: 返回 dp[m][n],从起始位置到达终点位置的路径数
    C++代码
class Solution 
{
public:int uniquePaths(int m, int n) {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++)dp[i][j] = dp[i - 1][j] + dp[i][j - 1];return dp[m][n];}
};

不同路径 II

题目:不同路径 II

在这里插入图片描述
思路

  • 状态表示:dp[i][j]表示走到[i, j]位置时,一共有多少种方式
  • 状态转移方程:到达[i, j]位置有两种方式
    • [i - 1, j][i, j]
    • [i, j - 1][i, j]
    • 如果某个位置[i - 1, j] 或者 [i, j - 1] 上存在障碍物, dp[i][j] = 0
    • 所以,状态转移方程为:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
  • 初始化:在 dp数组前添加一行和一列,初始化dp[0][1] = 1
  • 填表顺序:从上往下,从左往右
  • 返回值: 返回 dp[n][m],从起始位置到达终点位置的路径数
    C++代码
class Solution 
{
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int n  = obstacleGrid.size(), m = obstacleGrid[0].size();vector<vector<int>> dp(n + 1, vector<int>(m + 1));dp[0][1] = 1;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++){if(obstacleGrid[i - 1][j - 1] == 0)dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}return dp[n][m];}
};

珠宝的最高价值

题目:珠宝的最高价值

在这里插入图片描述
思路

  • 状态表示:dp[i][j]表示走到[i, j]位置时,此时的最大价值
  • 状态转移方程:到达[i, j]位置有两种方式
    • [i - 1, j][i, j]
    • [i, j - 1][i, j]
    • 需要选择其中最大价值的路径
    • 所以,状态转移方程为:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + frame[i - 1][j - 1]
  • 初始化:在 dp数组前添加一行和一列,将所有值初始化为零
  • 填表顺序:从上往下,从左往右
  • 返回值: 返回 dp[n][m],表示最大值

C++代码

class Solution 
{
public:int jewelleryValue(vector<vector<int>>& frame) {int n = frame.size(), m = frame[0].size();vector<vector<int>>dp(n + 1, vector<int>(m + 1));for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++){// 注意数组映射dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + frame[i - 1][j - 1]; }return dp[n][m];}
};

下降路径最小和

题目:下降路径最小和

在这里插入图片描述
思路

  • 状态表示:dp[i][j]表示走到[i, j]位置时,此时的最小的下降路径

  • 状态转移方程:到达[i, j]位置有三种方式

    • 正上方[i - 1, j][i, j]
    • 右上方[i + 1, j + 1][i, j]
    • 左上方[i - 1, j - 1][i, j]
    • 需要选择最小的下降路径
    • 所以,状态转移方程为:dp[i][j] = matrix[i - 1][j - 1] + min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i - 1][j + 1]))]
  • 初始化:添加了一行和两列,

    • 两列:将其值初始化为正无穷大
    • 一行:将其值初始化为 0,以保证后续填表时是正确的
  • 填表顺序:从上往下,从左往右

  • 返回值: 返回dp表中最后一行的最小值dp[n][i]

C++代码

class Solution 
{
public:int minFallingPathSum(vector<vector<int>>& matrix) {int n = matrix.size();vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX)); // 两列:将其值初始化为正无穷大for(int i = 0; i < n + 2; i++) dp[0][i] = 0; // 一行:将其值初始化为 0for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)dp[i][j] = matrix[i - 1][j - 1] + min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i - 1][j + 1]));int ret = INT_MAX;for(int i = 1;i <= n; i++)ret = min(ret, dp[n][i]);return ret;}
};

最小路径和

题目:最小路径和

在这里插入图片描述
思路

  • 状态表示:dp[i][j]表示走到[i, j]位置时,此时的最小的下降路径和

  • 状态转移方程:到达[i, j]位置有两种方式

    • 左方[i, j - 1][i, j]
    • 上方[i - 1, j][i, j]
    • 需要选择最小的下降路径
    • 所以,状态转移方程为:dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1]
  • 初始化:

    • 初始化所有位置为正无穷大
    • 特殊位置设置为0,即dp[0][1] = dp[1][0] = 0;
  • 填表顺序:从上往下,从左往右

  • 返回值: 返回dp[m][n]

C++代码

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];}
};

地下城游戏

题目:地下城游戏

在这里插入图片描述
思路

  • 状态表示:dp[i][j]表示,从[i, j]到达终点,所需的最低健康点数

  • 状态转移方程:到达[i, j]位置有两种方式

    • 下方[i + 1, j ][i, j]
    • 右方[i , j + 1][i, j]
    • 所以,状态转移方程为:dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]
    • 由于dungeon[i][j] 可能是一个较大的正数,计算得到的dp[i][j]的值可能会小于等于 0,所以我们将 dp[i][j] 1 取最大值,即dp[i][j]=max(1,dp[i][j])
    • 综上,dp[i][j] = max(1, min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j])
  • 初始化:我们在 dp 表的最后一行和最后一列分别添加一行和一列

    • 初始化所有位置为正无穷大
    • dp[m][n - 1] = dp[m - 1][n] = 1
  • 填表顺序:从下往上,从右往左

  • 返回值: 返回dp[0][0]

C++代码

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

http://www.mrgr.cn/news/56465.html

相关文章:

  • 微信小程序实现录音,播放录音功能
  • Linux 和Windows创建共享文件夹实现文件共享
  • 前端算法:字典and哈希表(力扣1题、349题解法)
  • Flux.using 使用说明书
  • 华为鸿蒙开发笔记
  • 爬虫阶段式教学——从数据获取到格式化存储(附代码与效果图)
  • 基于MATLAB(DCT DWT)
  • 在做题中学习(66):两数相加
  • 每日OJ题_牛客_字符串分类_哈希+排序_C++_Java
  • 算法Day-7
  • Log4j和SLF4J在Java中打印日志的区别
  • 大厂面试真题-Redis的Cluster模式的smart clent了解吗,怎么初始化的
  • 上传文件到云存储前端报错413 Request Entity Too Large
  • 智能工厂的软件设计 结构映射、类比推理及信念修正
  • AcWing 11 背包问题求方案数
  • MybatisPlus入门(一)MybatisPlus简介
  • 字节流写入文件
  • 理解CPU怎么执行一条指令
  • 【flask web】 Blueprint 蓝图 路由模块化
  • 2、图像的特征
  • 技术经济学·技术经济分析指标体系与基本原则
  • 在金融领域,机器学习算法优化的成功案例有哪些?
  • 【C++复习】Map Set HashMap HashSet的模拟实现{代码分享}
  • 马拉车算法(C/C++)
  • 3184. 构成整天的下标对数目 I
  • 车规芯片SOC简介