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

【算法】——动态规划之路径问题

目录

前言:

一、不同路径

二、不同路径(Ⅱ)

三、下降最小路径和

四、地下城游戏

总结:


前言:

动态规划的主要问题是状态表示和状态转移方程,而这两个步骤除了方法以外还需要经验的支撑,所以多刷题是很有必要的。那么今天我们来看一个动态规划中的路径问题。

路径问题与之前基础动态规划问题的区别主要在于二维dp数组。

一、不同路径

题目中给出了一个m*n的网格,然后让我们计算从左上角走到右下角一共有多少种不同路径。

1. 由于这是个二维表格(与之前一维不同),所以我们需要定义二维dp表,这样才能方便地对每一个位置表示,定义dp[ i ][ j ]表示走到[ i ][ j ]位置为止,一共有的路径数量。

2. 根据题目可知,我们只能向右或向下走,所以要走到[ i ][ j ]位置的话只可能从[ i - 1 ][ j ]或者是[ i ][ j - 1 ]这两个前置位置,那么dp[ i ][ j ]的值应该是这两个位置路径数量之和。可知状态转移方程为:dp[ i ][ j ] = dp[ i - 1 ][ j ] + dp[ i ][ j - 1 ]

3. 由状态转移方程可知dp[ i ][ j ]要用到左和上两个值,但第一排没有上面的值,第一列没有左边的值,为了方便统一使用状态转移方程,我们可以在最左和最上多申请一列,并初始化为0,这样就不会有越界访问的问题。而开始位置应该初始化为1,所以可以在多开的空间放一个1。(也可以不多开空间,单独对第一行和第一列分别初始化,但有些时候会比较麻烦,所以需要掌握这个技巧)

注意:动态规划中常会多开空间以方便初始化,但要对多开的空间进行合理初始化,来保证对整个过程没有影响

示例代码:

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m+1, vector<int>(n+1));// 创建一个二维dp表,多生成一行一列,便于遍历// dp[i][j]表示到dp[i][j]为止,一共有的路径数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];}
};

二、不同路径(Ⅱ)

这题与上一题的区别是多了障碍物,那么我们该怎么处理这个障碍物呢?

因为有障碍物的地点是到达不了的,所以有障碍物的坐标dp值应该置为0,而对于状态转移方程实际是没有影响的,因为dp[ i ][ j ]在障碍物右边或下面时,相当于加了一个0。所以状态转移方程可以加一个if判断条件。

示例代码:

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& ob) {int m = ob.size();int 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];}else{dp[i][j] = 0;}}}return dp[m][n];}
};

三、下降最小路径和

这道题要求下降最小路径和,即每次移动在垂直方向上都要下降一步,并且在水平方向上可以选择左右移动一步或不动。

1. 我们可以创建一个n * n的dp表,dp[ i ][ j ]表示走到[ i ][ j ]位置时,最小的下降路径和

2. 而dp[ i ][ j ]的值就等于,在上一排的左中右三个位置中选出一个最小值,也就是dp[ i-1 ][ j-1 ]、dp[ i-1 ][ j ]、dp[ i-1 ][ j+1 ]这三个位置,然后再加上[ i ][ j ]本身需要花费的值。所以状态转移方程为:dp[ i ][ j ] = min(min(dp[ i-1 ][ j-1 ], dp[ i-1 ][ j ]), dp[ i-1 ][ j+1 ]) + matrix[ i ][ j ]

3. 第一排初始化成matrix数组第一排的值即可。最左和最右两排比较特殊,只有两个值,可以选择多两排并初始化为一个最大值,但本次博主使用的是对这两排进行单独处理的方法。

示例代码:

class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {int n = matrix.size();vector<vector<int>> dp(n, vector<int>(n));// dp[i][j]表示走到dp[i][j]位置为止的路径最小和// 初始化第一排for(int i = 0; i < n; i++){dp[0][i] = matrix[0][i];}for(int i = 1; i < n; i++){for(int j = 0; j < n; j++){if(j == 0){dp[i][j] = min(dp[i-1][j], dp[i-1][j+1]) + matrix[i][j];}else if(j < n-1){dp[i][j] = min(min(dp[i-1][j-1], dp[i-1][j]), dp[i-1][j+1]) + matrix[i][j];}else{dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]) + matrix[i][j];}}}int min = dp[n-1][0];for(int i = 1; i < n; i++){if(dp[n-1][i] < min){min = dp[n-1][i];}}return min;}
};

四、地下城游戏

1. 这是本篇文章最难的一题,你会发现,如果按照常规的dp[ i ][ j ]表示到什么什么位置为止......很难解决问题,因为你无法确定开始时骑士需要的健康值。所以我们可以反过来,从终点开始往起点推,也就是从dp[ i ][ j ]表示从[ i ][ j ]为起点,到达终点所需的最低初始健康值。

2. 那么我们就可以反过来推,从dp[ i ][ j ]往起点走一步,那么他的最低健康值应该再减去那一步所需花费的健康值。又因为可以选择向右走或向下走,我们应该选择更小的那个,所以状态转移方程应该为:dp[ i ][ j ] = min(dp[ i+1 ][ j ], dp[ i ][ j+1 ]) - dungeon[ i ][ j ]。但数组中有正值,所以dp[ i ][ j ]减完可能为负数,但根据题目情况应保证他至少为1,所以还要加上:dp[ i ][ j ] = max(1, dp[ i ][ j ]);

3. 初始化可以在最又方和最下方多加一行一列,初始化为最大值,并在dp[ n ][ m-1 ]或dp[ n-1 ][ m ]赋值为1,表示到达终点后的健康值应为1。

示例代码:

class Solution {
public:int calculateMinimumHP(vector<vector<int>>& dungeon) {int m = dungeon.size();int n = dungeon[0].size();// dp[i][j]表示[i][j]位置开始,到达目标位置所需的最低初始健康点数vector<vector<int>> dp(m+1, vector<int>(n+1, INT_MAX));dp[m-1][n] = dp[m][n-1] = 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];dp[i][j] = max(1, dp[i][j]);// 最低健康值应至少为1}}return dp[0][0];}
};

总结:

以上便是本文的所有内容了,如果觉得有帮助的话可以点赞收藏加关注支持一下!

http://www.dtcms.com/a/470499.html

相关文章:

  • 阿里云企业建站教程泰州东方医院
  • 东阿县住房和城乡建设局网站申请做版主 再什么网站
  • 深入理解数据在内存中的存储:整数与浮点数的二进制表示
  • 广东网站营销seo费用品牌推广活动有哪些
  • 特效音网站建设公司官网制作平台
  • MySQL数据库安装后,如何设置自动化备份策略?
  • 【开题答辩全过程】以 保险业务信息管理系统为例,包含答辩的问题和答案
  • 进口食品销售销售在那个网站做seo托管
  • 公司模板网站建设成绩查询系统网站开发
  • 建设大淘客网站雅布设计师
  • Oracle ADRCI工具全面使用指南:从基础到故障诊断实战
  • 美食网站设计欣赏上海著名网站建设
  • 【智能系统项目开发与学习记录】bringup功能包详解
  • 外贸网建站建公司网站的详细步骤
  • 美食网站建设书成都seo技术
  • 江河建设集团有限公司网站梧州网站建设流程
  • 在Qt中使用VTK
  • 正安北郊湖吉他文化广场自动化监测
  • 【论文阅读】DSPy-based neural-symbolic pipeline to enhance spatial reasoning in LLMs
  • cn域名后缀网站163企业邮箱格式
  • psql常用命令
  • 高速公路自动车道保持系统原理与实现
  • 番禺做网站最便宜的哪家公司wordpress注册界面
  • 【推荐100个unity插件】将您的场景渲染为美丽的冬季风景——Global Snow 2
  • Windows安装Elasticsearch保姆级教程
  • 温州网站链接怎么做在山东省建设监理协会网站
  • C++中的父继子承:继承方式实现栈及同名隐藏和函数重载的本质区别, 派生类的4个默认成员函数
  • 32.渗透-.Kali Linux-工具-netcat的说明
  • Large Kernel Modulation Network for Efficient Image Super-Resolution 学习笔记
  • 城乡住房建设部网站杭州市萧山区哪家做网站的公司好