【动态规划】:路径问题_地下城游戏

朋友们、伙计们,我们又见面了,本专栏是关于各种算法的解析,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

​ 

目录

1. 题目解析

2. 算法原理

2.1 状态表示

2.2  状态转移方程

2.3 初始化

2.4 填表顺序

2.5 返回值

3. 代码实现

4. 算法复杂度


1. 题目解析

LeetCode174.地下城游戏:https://leetcode.cn/problems/dungeon-game/description/icon-default.png?t=N7T8https://leetcode.cn/problems/dungeon-game/description/

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

该题是一个二维的路径问题,根据题目描述,每次只能走一步,并且只能向下或者向右走,在走到该位置时会失去健康值,当健康值为0或者小于0时会死亡,左上角和右下角的位置也会失去对应的健康值,所以,我们需要在不死的前提下确定一个从左上角走到右下角的最小的初始血量。

2. 算法原理

解决路径问题常用的就是动态规划思想:

2.1 状态表示

关于路径问题我们通常是以某一位置为结束再根据题目要求进行表示:

以某一位置为结束:dp[i][j]就表示从开始走到[i, j]位置时所需的最小初始健康点数,如果这样子用来进行状态表示,那么会出现一个问题,要能走到[i, j]位置,还必须要能走到[i, j+1]和[i+1, j]的位置,因为当前位置的血量还会被下边和右边的位置所影响,因此这样表示是不能推出来状态转移方程;所以我们需要用某一开始位置进行定义:

以某一位置为开始:dp[i][j]就表示从[i][j]位置走到达终点时所需要的最小初始健康点数。

2.2  状态转移方程

根据状态表示:dp[i][j]表示的是从[i][j]位置走到终点所需要的最小初始健康点数,那么走到

[i, j]位置时,下一步有两种走法:

此时我们就可以假设初始血量为x,

① 向右[i, j+1]走一步,那么x + dungeon[i][j] >= dp[i][j + 1]

② 向下[i+1, j]走一步,那么x + dungeon[i][j] >= dp[i + 1][j]

因为我们需要求最小初始血量,根据上式换算将x换为dp[i][j]即可

dp[i][j] = min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j]

此时还存在一个问题,如果dungeon[i][j]是一个非常大的血包,也就是说上面的式子的结果成了负数,此时是不合理的,因为血量小于等于0就死亡了,因此如果遇见上面的情况,我们仅用一滴血就可以到达,所以需要将血量由负数转化为1即可。

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

2.3 初始化

根据状态表示和状态转移方程,我们在填当前位置的值时,需要用到右边的一个或者是下边的一个,那么位于最右边一列和最下面一行在填表时都存在越界的风险,所以我们在最右边一列再加一列,最下面一行再加一行。

那么只需要将多开的这一行,和这一列初始化即可,那么这些位置该怎么初始化呢?

① 先来看带有星星的位置,这个位置就是真实的最后一个位置,那么当我们走到这个位置,我们应该至少存在1滴血,所以它的右边和下边的初始化为1即可;

② 因为我们取的是右边或者下边的较小值,所以剩余位置设置为INT_MAX即可。

为了方便起,我们可以在创建dp表时就将所有的值都初始化为INT_MAX,然后只对特殊的两个位置初始化为1即可。

2.4 填表顺序

因为我们是以[i, j]位置为开始然后进行表述,所以我们的填表顺序应该是从下往上填每一行,每一行中从右往左。

2.5 返回值

根据状态表示,我们最终的返回值是dp[0][0]

3. 代码实现

class Solution 
{
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) 
    {
        int m = dungeon.size();
        int n = dungeon[0].size();
        // 创建dp表
        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]);
            }
        return dp[0][0];
    }
};

4. 算法复杂度

使用了两层for循环时间复杂度:O(M * N)

使用了二维dp表:空间复杂度:O(M * N)

朋友们、伙计们,美好的时光总是短暂的,我们本期的的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!        

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

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

相关文章

【LLM 论文】Least-to-Most Prompting 让 LLM 实现复杂推理

论文&#xff1a;Least-to-Most Prompting Enables Complex Reasoning in Large Language Models ⭐⭐⭐ Google Research, ICLR 2023 论文速读 Chain-of-Thought&#xff08;CoT&#xff09; prompting 的方法通过结合 few-show prompt 的思路&#xff0c;让 LLM 能够挑战更具…

MySQL#MySql表的操作

目录 一、创建表 二、查看表结构 三、修改表 1.修改表的名字 2.新增一个列 3.修改列 4.删除列 5.修改列的名称 四、删除表 一、创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校…

2042193-77-9,BDP FL甲基四嗪可用于标记细胞和组织样本

1.基本信息&#xff1a; BDP FL甲基四嗪是一种具有独特化学和光学性质的化合物。 2.化学结构&#xff1a; BDP FL甲基四嗪是含有甲基四嗪基团的BDP染料连接体。BDP FL部分是指附着在甲基四嗪上的荧光标记&#xff0c;使其在暴露于特定波长的光时能够发光。 甲基四嗪是一种具有…

C语言【文件操作 2】

文章目录 前言顺序读写函数的介绍fputc && fgetcfputcfgetc fputs && fgetsfputsfgets fprintf && fscanffprintffscanf fwrite && freadfwritefread 文件的随机读写fseek函数偏移量ftell函数rewind函数 文件的结束判断被错误使用的feof 结语 …

鸿蒙开发接口Ability框架:【(StaticSubscriberExtensionAbility)】

StaticSubscriberExtensionAbility StaticSubscriberExtensionAbility模块提供静态订阅者扩展能力的类别的能力。 说明&#xff1a; 本模块首批接口从API version 9 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下…

多线程学习D10 收尾了应该

线程安全集合类概述 重点介绍java.util.concurrent.* 下的线程安全集合类&#xff0c;可以发现它们有规律&#xff0c;里面包含三类关键词&#xff1a;Blocking、CopyOnWrite、Concurrent Blocking 大部分实现基于锁&#xff0c;并提供用来阻塞的方法 CopyOnWrite 之类容器修改…

iOS 17 / iPad OS 17屏蔽更新

iOS 17 / iPad OS 17屏蔽更新 1&#xff0c;进入屏蔽iOS更新的描述文件下载链接 下载链接 wx 搜索 Geek 前端发送屏蔽更新进行获取 2&#xff0c;复制这段链接&#xff0c;在Safari浏览器中打开&#xff0c;注意打开后别点击下载&#xff01;要先改时间&#xff01; 3&#…

69、oak和华为atlas 200dk A2进行编解码测试

基本思想:将oak深度相机与atlas 200dk A2进行结合,测试其dvpp的编解码能力 cmakelist.txt cmake_minimum_required(VERSION 3.16) project(untitled10) set(CMAKE_CXX_FLAGS "-std=c++11") set(CMAKE_CXX_STANDARD 11) add_definitions(-DENABLE_DVPP_INTERFACE)i…

数据的输入和输出

早期的总线系统 为了解决通信的问题、主板上铺设了一条公共线路、各个设备都连接到这条线路上、不管谁要和谁通信、都能使用它来传输、这条线路就是总线。 总线上有CPU、内存、鼠标、键盘、硬盘、网卡、声卡、显卡等… 说是一条总线、实际上是包含了传输数据的数据总线、传输…

保研面试408复习 4——操作系统、计网

文章目录 1、操作系统一、文件系统中文件是如何组织的&#xff1f;二、文件的整体概述三、UNIX外存空闲空间管理 2、计算机网络一、CSMA/CD 协议&#xff08;数据链路层协议&#xff09;二、以太网MAC帧MTU 标记文字记忆&#xff0c;加粗文字注意&#xff0c;普通文字理解。 1、…

「C++ 内存管理篇 00」指针

目录 一、变量&#xff0c;变量名和指针 1. 什么是变量&#xff1f; 2. 变量名和指针 3. 使用指针获取数据 二、指针变量和数组变量 三、编译器对指针的等级有着严格的检查 四、指针的加减 1. 存放指针的变量的加减 2. 存放指针的变量的自增自减 3. 两个指针相减 一、变量&…

融知财经:期货交易的规则和操作方法

期货交易是指在未来的某一特定时期&#xff0c;买卖双方通过签订合约的方式&#xff0c;约定以某种价格买卖一定数量的某种商品或资产的行为。期货交易的规则和操作方法如下&#xff1a; 期货交易的规则和操作方法 1、双向交易&#xff1a; 期货市场允许投资者进行多头&#xf…

数据结构_栈和队列(Stack Queue)

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 栈&#xff1a; 代码&#xff1a;function/数据结构_栈/stack.c 钦某/c-language-learning - 码云 - 开源中国 (gitee.com)https://gitee.com/wang-qin928/c-language-learning/blob/master/function/…

实战教程:个性化生鲜超市小程序制作与运营全解析

生鲜电商行业一直以来都备受关注&#xff0c;而如今&#xff0c;小程序商城成为了这个行业的新潮流。乔拓云平台提供了一个便捷的平台&#xff0c;让我们可以轻松地进入商城后台管理页面。 浏览器搜索【乔拓云】并登陆平台后&#xff0c;我们可以点击【小程序商城】模块&#x…

Redis学习汇总

目录 1.Linux环境下安装redis 2.redis的数据结构及命令 3.redis.conf配置文件常用配置 3.redis的事务操作 4.redis实现乐观锁 5.通过jedis操作redis 6.Springboot集成redis 7.自定义一个RedisTemplate 8.持久化策略 RDB和AOF 9.redis集群环境搭建 10.哨兵模式 11.缓…

Langchain实战

感谢阅读 LangChain介绍百度文心API申请申请百度智能云创建应用 LLMChain demo以及伪幻觉问题多轮对话的实现Sequential ChainsSimpleSequentialChainSequentialChainRouter Chain Documents ChainStuffDocumentsChainRefineDocumentsChainMapReduceDocumentsChainMapRerankDoc…

第09章 局域网技术(拓扑结构设计+FDDI工作机制)

9.1 本章目标 了解IEEE 802局域网标准掌握局域网拓扑结构了解10Base以太网了解快速以太网熟悉交换式以太网了解千兆位以太网了解其它种类的局域网局域网中的常用技术 9.2 局域网概述 罗伯特梅特卡夫个人简介 罗伯特梅特卡夫&#xff08;Robert Metcalfe&#xff0c;1…

第五节课《LMDeploy 量化部署 LLM 实践》

LMDeploy 量化部署 LLM-VLM 实践_哔哩哔哩_bilibili PDF链接&#xff1a;https://pan.baidu.com/s/1JFtvBWgEGFWJq8pHafvIUg?pwd6666 提取码&#xff1a;6666 https://github.com/InternLM/Tutorial/blob/camp2/lmdeploy/README.md 一、大模型部署背景 RAG范式开发大模型…

neo4j-5.11.0安装APOC插件or配置允许使用过程的权限

在已经安装好neo4j和jdk的情况下安装apoc组件&#xff0c;之前使用neo4j-community-4.4.30&#xff0c;可以找到配置apoc-4.4.0.22-all.jar&#xff0c;但是高版本neo4j对应没有apoc-X.X.X-all.jar。解决如下所示&#xff1a; 1.安装好JDK与neo4j 已经安装对应版本的JDK 17.0…

ABAP 第二代增强-采购申请子屏幕增强

文章目录 第二代增强-采购申请子屏幕增强需求实现过程创建项目运行效果客户屏幕的PBO全局变量获取数据更新数据运行效果查询底表修改数据 第二代增强-采购申请子屏幕增强 需求 实现过程 创建项目 运行效果 客户屏幕的PBO 全局变量 *&------------------------------------…
最新文章