在这里插入图片描述

最小路径和(medium)

64. 最小路径和

​ 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

​ **说明:**每次只能向下或者向右移动一步。

示例 1:

在这里插入图片描述

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 100

解题思路

​ 首先还是状态表示,依照路径问题的经验和题目要求,可以很容易的设定 dp[i][j] 表示到达 [i, j] 位置时的最小路径和

​ 接着就是状态转移方程,根据最近一步来推导的话,和 [i, j] 有关系的就是 [i-1, j][i, j-1] 这两格了,以前者为例,dp[i-1][j] 表示到达 [i-1, j] 位置时候的最小路径和,那么 dp[i, j] 想得到最小路径和,不就是 [i-1, j] 的最小路径和,加上 [i, j] 当前的大小 吗,很简单明了,对于 [i, j-1] 也同样如此!

​ 既然要的是最小的路径和,我们只需要取 dp[i-1][j]dp[i][j-1] 中小的那个加上当前的大小即可!

​ 所以状态转移方程为:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]

​ 然后还是初始化问题,因为我们要给表格加上虚拟行列,并且因为我们的状态转移方程是根据左边和上边格子得到的,这样子的话我们只需要多加一行一列,放在最上边和最左边这一行一列作为虚拟行列!

​ 现在考虑两个问题,①虚拟行列的初始值不能影响后面填表的正确;②下标的映射关系。

​ 其实最重要的还是第一个,因为我们在左上角开始遍历,需要让 dp[1][1] 得到的还是原来 gird 中的值,所以 得让 dp[0][1] 或者 dp[1][0] 为 0,保证加的时候加 0,就不会有影响了,而 其它位置都设为 INT_MAX,因为其它边界位置其实是不想收到这个虚拟行列的影响的,只希望收到附近的非虚拟位置的影响,所以用 INT_MAX 的时候进行最小值判断就不会取到它了!

在这里插入图片描述

​ 填表顺序就是从上往下,从左往右

​ 最后返回的就是右下角的值也就是到达右下角的最小路径和!

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX)); // 多开一行一列给虚拟行列,都设为INT_MAXdp[0][1] = 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];}
};

地下城游戏(hard)

174. 地下城游戏

​ 恶魔们抓住了公主并将她关在了地下城 dungeon右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。

​ 骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。

​ 有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。

​ 为了尽快解救公主,骑士决定每次只 向右向下 移动一步。

​ 返回确保骑士能够拯救到公主所需的最低初始健康点数。

**注意:**任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

示例 1:
在这里插入图片描述

输入:dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]]
输出:7
解释:如果骑士遵循最佳路径:右 -> 右 -> 下 -> 下 ,则骑士的初始健康点数至少为 7 。

示例 2:

输入:dungeon = [[0]]
输出:1

提示:

  • m == dungeon.length
  • n == dungeon[i].length
  • 1 <= m, n <= 200
  • -1000 <= dungeon[i][j] <= 1000

解题思路

​ 这道题乍一看和上面几道路径题好像差不多,但其实这道题隐藏很多细节,稍不注意就出错,至少我是这样子的!为什么这么说呢❓❓❓

​ 按我们上面做题的经验来看,我们都是以 [i, j] 为结尾怎么这么样这种情况,但是在这道题中,这种状态表示其实是不正确的,是推导不出来的,我们来举个例子:

在这里插入图片描述

​ 注意:上图中的例子只是为了表达这种状态表示是错误的,其实例子的一些细节是错误的,注意即可!

​ 所以我们就得改变一下思考方式,考虑从后面往前推导,也就是说以 [i, j] 为起点怎么怎么样这种情况,其实通过后面讲解会看到这样子是行得通的!

​ 所以我们的状态表示 dp[i][j] 表示以 [i, j] 为起点,到达终点也就是右下角的最低健康点数

​ 也就是说现在我们推导的就是 dp[0][0] 了,那么就得 从后往前推导

​ 接着就是状态转移方程,既然是从后往前推导,那么肯定是和当前格子的右边或者下边有关系。解释如下图:

在这里插入图片描述

​ 除此之外,上图中还解释了初始化的问题,并且我们并不需要去关心下标映射的问题,因为我们的虚拟行列是开在最后一行和最后一列!

​ 填表的顺序的话,就是从下往上,每行从右往左

​ 返回值就是左上角的值!

这样子就结束了吗❓❓❓

​ 结束就错了,还有一个细节我们没有处理!仔细想一下上面的状态转移方程,其中是涉及到了减法,要是遇到一种情况,就是 dungeon[i][j] 是一个正数,也就相当于这道题的一个加血点,如果它很大,导致减完之后得到的是一个负数,那么 dp[i][j] 是一个负数肯定是错误的啊,它表示的是最小健康点数,小于等于 0 不就挂了吗对不对!

​ 所以我们必须处理一下,为了让其减去一个很大的负数之后还能得到一个最小的健康点数,我们想到的就是 1,所以我们在执行完状态转移方程之后还必须做一次判断,或者直接处理这个数,使得 dp[i][j] 不会成为一个负数,如果是负数了,就让它变成最小的健康点数 1 即可,代码如下:

dp[i][j] = max(1, dp[i][j]);

class Solution {
public:int calculateMinimumHP(vector<vector<int>>& dungeon) {int m = dungeon.size();int n = dungeon[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX)); // 加入虚拟行列dp[m][n-1] = 1; // 将右下角的最近一步初始化为1,这样子的话保证了初始健康点数的q'z// 从下往上,从右往左填表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]); // 细节,不能遗漏}}return dp[0][0];}
};

在这里插入图片描述

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

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

相关文章

SQL详细语法教程(七)核心优化

以下对 SQL 优化 涉及的关键场景&#xff08;含 update 行锁优化&#xff09;进行极致详细的拆解&#xff0c;从底层原理、执行流程到实战代码、避坑指南全维度覆盖&#xff0c;搭配表格对比让逻辑更清晰&#xff1a;一、SQL 优化 - COUNT 优化1. 底层原理&#xff1a;COUNT() …

Tomcat 的核心脚本catalina.sh 和 startup.sh的关系

catalina.sh 和 startup.sh 都是 Tomcat 的核心脚本&#xff0c;但它们的角色和使用场景有所不同。以下是它们的主要区别和适用场景&#xff1a;1. 功能区别脚本主要用途底层调用关系startup.sh一个快捷入口脚本&#xff0c;用于快速启动 Tomcat&#xff08;后台模式&#xff0…

飞算JavaAI:简易贪吃蛇小游戏

目录先确定核心功能技术选型核心功能实现过程1. 数据模型设计2. 游戏界面和绘制逻辑3. 游戏主框架和事件处理飞算JavaAI在开发中的应用体验可以进一步优化的地方作为Java课程的小作业&#xff0c;不想做太复杂的管理系统&#xff0c;就选了贪吃蛇这个经典小游戏。全程用Swing做…

如何保障内部网络安全前提下,实现与外部互联网之间的文件传输?

在数字化时代&#xff0c;企业网络环境日益复杂&#xff0c;普遍采用“内外网隔离”的安全架构&#xff1a;内部办公网承载业务系统与数据&#xff0c;外部互联网则用于对外沟通与信息获取。这种隔离有效抵御了外部攻击&#xff0c;但也带来了“信息孤岛”问题——如何在保障内…

计算机视觉 图片处理 在骨架化过程中,每次迭代都会从图像的边缘移除一层像素,直到只剩下单像素宽度的骨架

你说得对&#xff0c;if cv2.countNonZero(binary) 0: break 这个条件确实表示图像中已经没有非零像素&#xff0c;即图像完全变为空白。这并不是骨架化完成的标志&#xff0c;而是表示图像已经被腐蚀到没有任何内容了。 在骨架化过程中&#xff0c;我们需要一个更合适的停止条…

rt-thread audio框架移植stm32 adc+dac,用wavplayer录音和播放

D1 参考 rt-thread官方sdk中&#xff0c;正点原子stm32f429-atk-appollo的board中有audio文件夹&#xff0c;包括了mic/play的程序&#xff0c;wm8978的库文件因为我们基于stm32h750内置adcdac设计&#xff0c;所以不需要wm8978.c/h。只需要移植drv_sound.c和drv_mic.c D2 工程…

AI重塑软件测试:质量保障的下一站

软件开发的世界变化飞快&#xff0c;系统越来越复杂&#xff0c;用户的胃口越来越大&#xff0c;产品上线的压力也越来越大。作为测试工程师&#xff0c;你是不是常常觉得传统测试已经跟不上节奏了&#xff1f;手工测试累死人&#xff0c;自动化脚本维护到崩溃&#xff0c;测试…

【前端基础知识系列六】React 项目基本框架及常见文件夹作用总结(图文版)

在 React 开发中&#xff0c;一个清晰合理的项目结构不仅能提高开发效率&#xff0c;还能让代码更易于维护和扩展。尤其是在团队协作中&#xff0c;统一的项目结构规范至关重要。本文将通过图文结合的方式&#xff0c;详细介绍 React 项目的基本框架以及常见文件夹的定义与作用…

0815 UDP通信协议TCP并发服务器

Part 1.思维导图一.UDP通信协议1.原理服务器端&#xff1a;1.用socket函数创建一个套接字文件2.创建服务器端地址结构体并赋值3.用ford函数将套接字文件与地址结构体绑定4.创建接收客户端地址结构体5.利用sendto和recvfrom函数传输和接收信息客户端&#xff1a;1.用socket函数创…

一个基于纯前端技术实现的五子棋游戏,无需后端服务,直接在浏览器中运行。

一 功能特性1.1 核心游戏功能- **标准五子棋规则**&#xff1a;1515棋盘&#xff0c;黑子(玩家)先手 - **AI对战模式**&#xff1a;白子AI具有中等难度&#xff0c;会进行智能进攻和防守 - **胜负判定**&#xff1a;支持横向、纵向、斜向五子连线获胜 - **平局检测**&#xff1…

HBuilderX升级,Vue2 scss 预编译器默认已由 node-sass 更换为 dart-sass

目录 一、问题描述 二、问题原因 三、问题解析及解决方案 一、问题描述 最近开发新项目&#xff0c;升级了HBuilderX版本到4.75&#xff0c;最近要在之前的项目添加功能的时候发现报错&#xff0c;错误如下&#xff1a;Vue2 scss 预编译器默认已由 node-sass 更换为 dart-sa…

像素风球球大作战 HTML 游戏

像素风球球大作战 HTML 游戏 下面是一个简单的像素风格球球大作战 HTML 游戏代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-widt…

文件导出时无法获取响应头Content-Disposition的文件名

1. 为什么Content-Disposition无法获取&#xff1f; 要拿到 Content-Disposition 里的 filename&#xff0c;可以用正则或者简单的字符串解析。 浏览器默认不让前端访问非标准响应头&#xff0c;Content-Disposition 需要后端显式暴露。 在浏览器开发者工具 → Network → Re…

Leetcode 128. 最长连续序列 哈希

原题链接&#xff1a; Leetcode 128. 最长连续序列 解法1: map&#xff0c;不符合要求 class Solution { public:int longestConsecutive(vector<int>& nums) {if (nums.size()0) return 0;map<int,int> mp;for(auto x: nums){mp[x];}int pre;int l0,r0,res0;…

禾赛激光雷达AT128P/海康相机(2):基于欧几里德聚类的激光雷达障碍物检测

目录 一、参考连接 二、实验效果​编辑 三、安装相应的 ros 依赖包 四、代码驱动 4.1 代码下载 4.2 代码文件放置(请按照这个命名放置代码) 4.3 代码编译 4.4 报错 一、参考连接

Vue Router的常用API有哪些?

文章目录一、路由配置相关二、路由实例方法&#xff08;router 实例&#xff09;三、组件内路由 API&#xff08;useRouter / useRoute&#xff09;四、导航守卫&#xff08;路由拦截&#xff09;五、路由视图与导航组件六、其他常用 API七、history模式和hash模式有什么区别&a…

从现场到云端的“通用语”:Kepware 在工业互联中的角色、使用方法与本土厂商(以胡工科技为例)的差异与优势

从现场到云端的“通用语”&#xff1a;Kepware 在工业互联中的角色、使用方法与本土厂商&#xff08;以胡工科技为例&#xff09;的差异与优势 文章目录从现场到云端的“通用语”&#xff1a;Kepware 在工业互联中的角色、使用方法与本土厂商&#xff08;以胡工科技为例&#x…

深入理解Prompt构建与工程技巧:API高效实践指南

深入理解Prompt构建与工程技巧&#xff1a;API高效实践指南 引言 Prompt&#xff08;提示&#xff09;工程是推动大模型能力极限的关键手段。合理的Prompt不仅能显著提升模型输出的相关性与准确性&#xff0c;在实际落地的API接口开发中同样起到举足轻重的作用。本文将系统介…

C++之多态(从0到1的突破)

世间百态&#xff0c;每个人都扮演着不同的角色&#xff0c;都进行着不同的行为。C更是如此&#xff0c;C中也会出现有着不同行为的多种形态的出现&#xff0c;那就让我们一起进入C的多态世界吧&#xff01;&#xff01;&#xff01; 一. 多态的概念 多态&#xff0c;顾名思义&…

路由器NAT的类型测定

目前所使用的NAT基本都是NAPT&#xff0c;即多端口的NAT技术&#xff0c;因此本文主要是设计了两种测定路由器NAPT类型的实验。 实验环境 设备 主机A&#xff1a;Windows主机B&#xff1a;Windows路由器 软件 ncWiresharkSocketTools 在局域网内部完成所有测试&#xff0c;完全…