动态规划-路径问题

文章目录

  • 1. 不同路径(62)
  • 2. 不同路径 II(63)
  • 3. 珠宝的最高价值(LCR 166)
  • 4. 下降路径最小和(931)
  • 5. 最小路径和(64)
  • 6. 地下城游戏(174)


1. 不同路径(62)

题目描述:
在这里插入图片描述
状态表示:
设dp[i][j]表示到达(i,j)位置时的路径数目。
状态转移方程:
dp[i][j]=dp[i-1][j]+dp[i][j-1]。这里分析起来很简单,因为这算是很经典的问题了。机器人只能向下或者向右走,所以到达(i,j)就有两种方式,分别是从(i-1,j)向下以及(i,j-1)向右,那么到达(i,j)位置的路径数只需要将到达(i-1,j)以及(i,j-1)位置的路径数相加即可。
初始化:
初始化就是为了避免越界问题,因为这里的状态转移方程涉及到i-1以及j-1。这里可以在矩阵外添加一行和一列,至于对于一行和一列的初始化要注意不能影响最终输出的结果,另外这样初始化还要注意下标的映射关系,这东西讲不清具体得看代码,这样初始化的好处就是可以将一整个矩阵全写进循环。
填表顺序:
从上到下,从左至右。
返回值:
因为添加了一行一列所以返回dp[m][n]。
代码如下:

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m + 1][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];


    }
}

题目链接
时间复杂度:O(n^2)
空间复杂度:O(n^2)

2. 不同路径 II(63)

题目描述:
在这里插入图片描述
状态表示:
和上一题一样(i,j)位置的路径数为dp[i][j]。
状态转移方程:
实际上这题的状态转移方程也非常类似于上一题,但是要考虑一个特殊情况,就是障碍的情况。当(i,j)是障碍物的情况下直接将dp[i][j]=0,当(i,j)不是障碍物的情况下dp[i][j]=dp[i-1][j]+dp[i][j-1]。
初始化:
这里的初始化和上一题是一致的额,没什么好说的。。但是要提前判断左上角为障碍物的情况,直接返回0。
填表顺序:
从上往下,从左至右。
返回值:
与上题一致也是返回dp[m][n]。
代码如下:

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;

        int[][] dp = new int[m + 1][n + 1];

        dp[0][1] = 1;
        if (obstacleGrid[0][0] == 1) {
            return 0;
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (obstacleGrid[i - 1][j - 1] == 1) {
                    dp[i][j] = 0;
                } else {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }

        return dp[m][n];

    }
}

题目链接
时间复杂度:O(n^2)
空间复杂度:O(n^2)

3. 珠宝的最高价值(LCR 166)

题目描述:
在这里插入图片描述
状态表示:
这题与上面两题也是相似的,只不过给出的矩阵多出了一个值的属性,说白了这篇博客就是将路径问题进行的一个分类总结。这题的状态表示根据经验和题目要求可以设置为dp[i][j]表示在(i,j)位置能够拿到的最大珠宝价值。
状态转移方程:
到达(i,j)位置还是只能够从(i-1,j)以及(i,j-1),因此要得到(i,j)位置的最大价值首先要将dp[i-1][j]与dp[i][j-1]的价值进行比较得到最大值赋给dp[i][j],状态转移方程为dp[i][j]=max(dp[i-1][j],dp[i][j-1])+frame[i][j]。
初始化:
还是类似加上一行和一列,但是这里不用做别的操作了,行和列赋0即可。但是还要注意dp数组与frame数组的映射关系。
填表顺序:
从上到下,从左至右。
返回值:
dp[m][n]。
代码如下:

class Solution {
    public int jewelleryValue(int[][] frame) {
        int m = frame.length;
        int n = frame[0].length;

        int[][] dp = new int[m + 1][n + 1];

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + frame[i - 1][j - 1];
            }
        }

        return dp[m][n];
    }
}

题目链接
时间复杂度:O(n^2)
空间复杂度:O(n^2)

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

题目描述:
在这里插入图片描述
状态表示:
根据经验加题目要求可以将dp[i][j]定义为到达(i,j)位置的最小路径和。
状态转移方程:
(i,j)上一行相邻的位置有(i-1,j)(i-1,j-1)(i-1,j+1),因此要求得到达(i,j)位置的最小路径和就可以列出以下状态转移方程,dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+ matrix[i][j]。
初始化:
要避免到达(i,j)位置的前三个位置越界可以在矩阵上加上左右两边的两列以及上边的一行,从而方便后续的操作,这里为了避免加上的空间影响最终得到的结果要注意把加上的一行赋值为0,加上的两列赋值为无穷大。
填表顺序:
从上到下,从左至右。
返回值:
要返回矩阵最后一行的最小值。
代码如下:

class Solution {
    public int minFallingPathSum(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;

        int[][] dp = new int[m + 1][n + 2];

        for (int i = 0; i <= m; i++) {
            dp[i][0] = Integer.MAX_VALUE;
        }

        for (int i = 0; i <= m; i++) {
            dp[i][n + 1] = Integer.MAX_VALUE;
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i - 1][j + 1])) + matrix[i - 1][j - 1];
            }
        }

        int min = Integer.MAX_VALUE;
        for (int i = 1; i <= n; i++) {
            if (min > dp[m][i]) {
                min = dp[m][i];
            }
        }

        return min;
    }
}

题目链接
时间复杂度:O(n^2)
空间复杂度:O(n^2)

5. 最小路径和(64)

题目描述:
在这里插入图片描述
状态表示:
经验加题目要求,设定dp[i][j]表示到达(i,j)位置的最小路径和。
状态转移方程:
因为只能向下以及向右移动,所以dp[i][j]的值关联于dp[i-1][j]以及dp[i][j-1],即dp[i][j]=min(dp[i][j-1],dp[i-1][j])+grid[i][j]。
初始化:
也是一样为了避免越界,要给dp加上一行和一列的空间,这里要考虑到不能影响到最终的结果,因此除了左上角的左边和上边的空间其余空间都赋为无穷大。
填表顺序:
从上到下,从左至右。
返回值:
因为增加了一行和一列,所以应该返回dp[m][n]。
代码如下:

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;

        int[][] dp = new int[m + 1][n + 1];

        for (int i = 0; i < n + 1; i++) {
            dp[0][i] = Integer.MAX_VALUE;
        }

        for (int i = 0; i < m + 1; i++) {
            dp[i][0] = Integer.MAX_VALUE;
        }
        dp[0][1] = 0;

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
            }
        }

        return dp[m][n];
    }
}

题目链接
时间复杂度:O(n^2)
空间复杂度:O(n^2)

6. 地下城游戏(174)

题目描述:
在这里插入图片描述
状态表示:
根据经验以及题目要求这题定义dp[i][j]为以(i,j)为起点到达终点所需的最小点数。
状态转移方程:
根据经验与题目要求dp[i][j]定义为以位置(i,j)为起点营救公主所需的最低血量。因此位置(i,j)和其下边以及右边的dp元素的关系如下:
dp[i][j]+dungeon[i][j]>=dp[i+1][j]。
dp[i][j]+dungeon[i][j]>=dp[i][j+1]。
要满足以上条件,皆取最小值,即dp[i][j]=min(dp[i+1][j]-dungeon[i][j],dp[i][j+1]-dungeon[i][j]),不过要注意一个问题,当dungeon[i][j]的值是一个很大的值即一个很大的血包的时候,dp[i][j]就为负值了,要避免这种情况,如果出现血包很大的情况就将dp[i][j]直接赋为1即可,因为1就是逻辑上合理的最低血量。
初始化:
为了避免越界也要在dp上再多加一行和一列,这里的行和列是加在最后一行和最后一列。为了使添加之后不影响输出的结果,所以在行和列的每一个空间赋无穷大,只有右下角公主所在的位置的右边和下边赋为1,因为在逻辑上当营救完公主之后血量至少为1。
填表顺序:
从下到上,从右至左。
返回值:
dp[0][0]。
代码如下:

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        int m = dungeon.length;
        int n = dungeon[0].length;

        int[][] dp = new int[m + 1][n + 1];

        for (int i = 0; i <= m; i++) {
            dp[i][n] = Integer.MAX_VALUE;
        }

        for (int i = 0; i <= n; i++) {
            dp[m][i] = Integer.MAX_VALUE;
        }

        dp[m][n - 1] = 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] = Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];
                dp[i][j] = Math.max(1, dp[i][j]);
            }
        }

        return dp[0][0];

    }
}

题目链接
时间复杂度:O(n^2)
空间复杂度:O(n^2)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

程序员Java.vue,python前端后端爬虫开发资源分享

bat面试资料 bat面试题汇总 提取码&#xff1a;724z 更多资料

【日常记录】【CSS】生成动态气泡小球

文章目录 1、分析2、实现 1、分析 核心有两点&#xff0c;通过这两个不一样就可以实现每个小球的颜色、动画时间不一致 给每个元素都设置一个css 变量 bgc 用于控制每一个小球的颜色给每个元素都设置一个css 变量 duration 用于控制每一个小球的时间 2、实现 <!DOCTYPE ht…

学习javaEE的日子 Day36 字符流

Day36 1.字符流 应用场景&#xff1a;操作纯文本数据 注意&#xff1a;字符流 字节流编译器 编译器&#xff1a;可以识别中文字符和非中文字符&#xff0c;非中文字符获取1个字节&#xff08;一个字节一个字符&#xff09;&#xff0c;编译器会根据编码格式获取中文字符对应的…

造船业的重要工具之一(火工平台)——河北北重厂家

火工平台是造船业的重要工具之一&#xff0c;它是用于火焰切割和焊接的设备。在造船过程中&#xff0c;需要对金属材料进行切割和焊接&#xff0c;以构建船体结构。火工平台可以提供高温火焰&#xff0c;使得金属材料可以被切割或焊接。 火工平台通常由两个主要部分组成&#…

武汉星起航顺应政策东风,打造跨境电商孵化新标杆

在国家政策的鼎力支持下&#xff0c;跨境电商行业迎来了蓬勃发展的黄金时期。武汉星起航电子商务有限公司作为行业的佼佼者&#xff0c;积极响应国家政策号召&#xff0c;凭借专业的运营团队和丰富的经验&#xff0c;成功打造了一站式的跨境电商亚马逊孵化平台&#xff0c;为合…

【问题篇】activiti工作流流程图更新后旧数据问题

互相学习交流 当我们使用activiti开发工作流时&#xff0c;项目上线后可能修改需求导致修改流程图也是很常见的情况。但是activiti更新流程图后&#xff0c;以前的流程实例并不会也跟着更新&#xff0c;activiti会保存每一份的流程图版本&#xff0c;只有新发起的流程实例才会…

工控 modbusTCP 报文

Tx 发送报文:00 C9 00 00 00 06 01 03 00 00 00 02 Rx 接收报文:00 C9 00 00 00 07 01 03 04 01 4D 00 01 Tx 发送报文:00 C9 00 00 00 06 01 03 00 00 00 02 00 C9 事务处理标识符 2字节 00 00 协议标识符 2字节 固定 00 00 00 06 长度 2字节 表示之后的字节总数 &#xff08;…

llama-factory SFT系列教程 (三),chatglm3-6B 命名实体识别实战

背景 llama-factory SFT系列教程 (一)&#xff0c;大模型 API 部署与使用llama-factory SFT系列教程 (二)&#xff0c;大模型在自定义数据集 lora 训练与部署本文为llama-factory SFT系列教程 第三篇 简介 利用 llama-factory 框架&#xff0c;基于 chatglm3-6B 模型 做命名…

.NET SignalR Redis实时Web应用

环境 Win10 VS2022 .NET8 Docker Redis 前言 什么是 SignalR&#xff1f; ASP.NET Core SignalR 是一个开放源代码库&#xff0c;可用于简化向应用添加实时 Web 功能。 实时 Web 功能使服务器端代码能够将内容推送到客户端。 适合 SignalR 的候选项&#xff1a; 需要从服…

centos 7 sshd服务无法自动随机启动

centos 7 sshd 服务无法伴随主机启动而启动&#xff0c;而使用systemctl start sshd可以启动&#xff0c;很奇怪。 后来使用Kimi查询&#xff0c;有提示“检查系统启动服务的顺序和状态” systemctl list-dependencies <service>确保所有依赖服务都已正常启动。 查看本…

ArcGIS Desktop使用入门(三)图层右键工具——标注要素、将标注转换为注记

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…

python基础——类【类的定义和使用、魔术方法】

&#x1f4dd;前言&#xff1a; python中的类&#xff0c;自我感觉在某种程度上和C语言的结构体是有共同之处的&#xff0c;如果有兴趣&#xff0c;可以先看看这篇文章&#xff1a;C语言——结构体类型&#xff08;一&#xff09;&#xff0c;先了解一下C语言中的结构体&#x…

使用springboot整合shiro进行登录认证(md5+盐值+散列次数)

准备工作&#xff1a; md5加密算法&#xff1a; public class md5Test {Testpublic void md5() {//明文(123) 盐值(monian) 加密次数(1024) > 密文 8ea680082c12d7d878a3a97214ebbdc2Md5Hash md5Hash new Md5Hash("123","monian",1024);System…

【蓝桥杯嵌入式】串口通信与RTC时钟

【蓝桥杯嵌入式】串口通信与RTC时钟 串口通信cubemx配置串口通信程序设计 RTC时钟cubemx配置程序设计 串口通信 cubemx配置 打开串口通信&#xff0c;并配置波特率为9600 打开串口中断 重定义串口接收与发送引脚&#xff0c;默认是PC4&#xff0c;PC5&#xff0c;需要改为P…

vue3 依赖-组件tablepage-vue3说明文档,列表页快速开发,使用思路及范例(Ⅳ)其他配置项

vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅰ&#xff09;配置项文档 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅱ&#xff09;搜索及数据获取配…

STL函数对象

1&#xff0c;函数对象 1.1 函数对象概念 概念&#xff1a; 重载函数调用操作符的类&#xff0c;其对象常称为函数对象函数对象使用重载的&#xff08;&#xff09;时&#xff0c;行为类似函数调用&#xff0c;也称为仿函数 本质&#xff1a; 函数对象&#xff08;仿函数&…

国外站群服务器有哪几种?

国外站群服务器种类繁多&#xff0c;它们各具特色&#xff0c;适用于不同的业务需求和场景。以下将为您科普几种常见的国外站群服务器及其特点。 首先&#xff0c;美国站群服务器以其丰富的IP资源和强大的网络技术著称。作为全球网络技术和数据中心发展的领先者&#xff0c;美国…

僵尸进程和孤儿进程

目录 引言僵尸进程僵尸进程的状态僵尸进程周边知识 孤儿进程孤儿进程的状态 进程中的其他状态①.R---表示进程运行状态。②.S---表示进程的休眠状态。(进程什么都没做)③T 和 t 进程的运行、阻塞和挂起运行阻塞挂起状态&#xff1a; 引言 今天我们来将僵尸进程和孤儿进程以及其…

matlab使用教程(42)—常见的二维图像绘制方法

这个博客用于演示如何在 MATLAB 中创建曲线图、条形图、阶梯图、误差条形图、极坐标图、针状图、散点图。 1.曲线图 plot 函数用来创建 x 和 y 值的简单线图。 x 0:0.05:5; y sin(x.^2); figure plot(x,y) 运行结果&#xff1a; 线图可显示多组 x 和 y 数据。 x 0:0.05:…

如何正确使用数字化仪前端信号调理?(二)

在上期文章如何正确使用数字化仪前端信号调理&#xff1f;&#xff08;一&#xff09;中&#xff0c;我们为大家介绍了数字化仪前端电路所需的特性以及使用过程中需要的输入抗阻和输入耦合&#xff0c;本期文章将为您介绍数字化仪前端信号调理的使用过程中所需的输入电压范围&a…