【每日易题】Leetcode上Hard难度的动态规划题目——地下城游戏的实现

在这里插入图片描述

君兮_的个人主页

即使走的再远,也勿忘启程时的初心

C/C++ 游戏开发

Hello,米娜桑们,这里是君兮_,博主最近一直在钻研动态规划算法,最近在Leetcode上刷题的时候遇到一个Hard难度的动态规划题,今天就借此机会来给大家分享一下我对这个题目的一些看法和解题思路(放心,我是AC了的)

  • 好了废话不多说,开始我们今天的学习吧!!

地下城游戏

  • Leetcode上的原题链接在这里:地下城游戏

在这里插入图片描述

在这里插入图片描述

  • 好好好,一看题目里一大堆字还看不懂它到底什么意思,再看看上面标的hard难度,一大堆人相信和博主一样上来就准备先点击退出了,大家先不要捉急,我来带大家一步一步分析一下这个题目的意思

题目解析

在这里插入图片描述
(ps:这个在漫画里真是公主)

  • 我们的公主被抓住关在了最右下角,如图所示
    在这里插入图片描述
  • 接下来,我们的骑士要从图中位置出发,其中遇到恶魔(也就是格子里的值为负值)就需要与它们战斗会扣血,当遇到魔法球(图中为正值),就可以回血。此时,题目问我们,在初始位置时,骑士至少需要多少血(规定当在某个位置血量大于等于1即可通过否则失败)
  • 那么,通过题目的描述,结合之前我们学过的动态规划思想,你发现什么不一样了吗?作为Hard难度的题,想用常规的思维来解决肯定是不可能的,好了,接下来我带大家具体分析一下其中的算法原理吧

算法原理

1. 状态表示

  • 我们之前在动态规划的算法中说过,遇到动态规划问题时,一般的解决方式就是分两种情况:
    • (1) 选择某一个位置为终点结束,建立dp表,进行状态表示
    • 2)选择某一个位置为起点出发…
  • 按照常规思路,我们既然知道了公主的位置,那正常情况就是选择第一种情况来试着进行状态表示
  • 这道题如果我们照着这个思路定义成:从起点开始,到达[i, j] 位置的时候,所需的最低初始健康点数。
  • 那么我们分析状态转移的时候会有⼀个问题:那就是我们当前的健康点数还会受到后面的路径的影响。也就是从上往下的状态转移不能很好地解决问题。

这里是为什么呢?我们设想一下,假设此时我们骑士的血很少,下一格无论是朝下还是朝右都会遇到恶魔把我们骑士的血扣为负数,那此时这里的dp值合理吗?很显然是不合理的。因此我们出了考虑前面位置的情况,还要考虑后面路径的情况,岂不是太麻烦了?

  • 这个时候我们要换⼀种状态表示:从[i, j] 位置出发,到达终点时所需要的最低初始健康点数。这样我们在分析状态转移的时候,前面的路径不需要考虑,后续的最佳状态已经知晓,这样就极大的简化了我们分析的难度。

  • 综上所述,定义状态表示为:
    dp[i][j] 表示:从[i, j] 位置出发,到达终点时所需的最低初始健康点数


2 状态转移方程

  • 对于 dp[i][j] ,从 [i, j] 位置出发,下⼀步会有两种选择(为了方便理解,设 dp[i][j] 的最终答案是 x):

  • i. ⾛到右边,然后⾛向终点

  • 那么我们在 [i, j] 位置的最低健康点数加上这⼀个位置的消耗,应该要⼤于等于右边位置的最低健康点数,也就是: x + dungeon[i][j] >= dp[i][j + 1] 。
    通过移项可得: x >= dp[i][j + 1] - dungeon[i][j] 。因为我们要的是最⼩值,因此这种情况下的 x = dp[i][j + 1] - dungeon[i][j]

  • ii. ⾛到下边,然后⾛向终点

  • 那么我们在 [i, j] 位置的最低健康点数加上这⼀个位置的消耗,应该要⼤于等于下边位置的最低健康点数,也就是: x + dungeon[i][j] >= dp[i + 1][j] 。
    通过移项可得: x >= dp[i + 1][j] - dungeon[i][j] 。因为我们要的是最⼩值,因此这种情况下的 x = dp[i + 1][j] - dungeon[i][j]

  • 综上所述,我们需要的是两种情况下的最⼩值,因此可得状态转移⽅程为:
    dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]

  • 但是,如果当前位置的 dungeon[i][j] 是⼀个⽐较⼤的正数的话, dp[i][j] 的值可能变成 0 或者负数。也就是最低点数会⼩于 1 ,那么骑⼠就会死亡。因此我们求出来的 dp[i][j] 如果⼩于等于 0 的话,说明此时的最低初始值应该为 1 。处理这种情况仅需让 dp[i][j] 与 1 取⼀个最⼤值即可:
    dp[i][j] = max(1, dp[i][j])

什么意思呢?就是这里的[i,j]会给恢复一大口血,但是如果此时的dp[i,j]为负数的时候,说明此时这里要求的骑士的最低血量是0或者负数,这显然是不符合要求的,因此我们需要对这种特殊情况进行一下上述的这种处理

初始化

  • 可以在最前⾯加上⼀个「辅助结点」,帮助我们初始化。使⽤这种技巧要注意两个点:
  • i. 辅助结点⾥⾯的值要「保证后续填表是正确的」;
  • ii. 「下标的映射关系」。

有关辅助节点的使用方法在上面链接的博客中讲过了,这里就不再详叙

  • 在本题中,由于我们要考虑后面路径对现在位置的影响,需要在dp表最后面添加一行,并且添加⼀列后,所有的值都先初始化为无穷大,然后让dp[m][n - 1] 或dp[m - 1][n] = 1 即可。

填表顺序

  • 根据「状态转移方程」,我们需要「从下往上填每一行」,「每一行从右往左填」。看了上面的算法分析这一点应该不难理解

返回值

  • 从题目中可知,我们的骑士是从左上角开始的,因此结合上述分析,我们需要返回的值为dp[0][0]

编写代码

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][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];}
};
  • 代码很简单,只有十几行,实际上难的是上面分析题目的过程以及对一些特殊情况的判断,代码这里相信如果你能看懂上述原理的分析,这点对你来说应该一点都不难。

总结

  • 好啦,我们今天的内容就先到这里啦!其实代码并不重要,能看懂背后隐藏的原理并且通过这个题目学会对应题目的分析才重要,因此如果你想真正学会的话,不妨自己从头试着理解一下算法原理再自己独立编写代码,这样我相信是最能提升自己有关动态规划题目的理解的。
  • 有任何的问题和对文章内容的疑惑欢迎在评论区中提出,当然也可以私信我,我会在第一时间回复的!!

新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下再走呗。你们的支持就是我更新的动力!!!

**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**

在这里插入图片描述

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

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

相关文章

win11 install oh-my-posh

安装配置 下载 Nerd Fonts 字体 oh-my-posh font installNerd Fonts 网站下载&#xff0c;解压后右击安装 为终端设置 Nerd Fonts 字体 修改 Windows 终端设置&#xff08;默认快捷方式&#xff1a;CTRL SHIFT ,&#xff09;&#xff0c;在settings.json文件defaults属性下添…

在Linux上优化HTTP服务器的性能

在Linux上优化HTTP服务器的性能是一个涉及多个方面的任务&#xff0c;包括服务器硬件、网络设置、软件配置和内容优化。以下是一些关键的优化建议&#xff1a; 选择合适的HTTP服务器软件 Linux上有多种HTTP服务器软件&#xff0c;如Apache、Nginx、Lighttpd等。选择适合您需求…

uView ui 1x uniapp 表格table行内容长度不一导致高度不统一而出现的不对齐问题

问题 因为td单元格内空长度不定导致行单元格未对齐 解决&#xff1a; 重置td的高度&#xff1a;height:100% 改为height:auto !import <u-table><u-tr v-for"(item,index) in Lineinfo.Cust_Name" ><u-td style"height: auto !important;back…

8_企业架构缓存中间件分布式memcached

企业架构缓存中间件分布式memcached 学习目标和内容 1、能够理解描述网站业务访问流程 2、能够理解网站业务的优化方向 3、能够描述内存缓存软件Memcached的作用 4、能够通过命令行操作Memcached 5、能够操作安装php的memcached扩展 extension 6、能够实现session存储到memcach…

前端vue导出PPT幻灯片,使用pptxgen.js,超详细(赋原数据)

即上一篇文章最终代码 前端vue导出PPT&#xff0c;使用pptxgen.js 前端vue导出PPT&#xff0c;使用pptxgen.js 一个平台下有10个国家&#xff0c;这个是后端返回数据固定的&#xff0c;每一个国家下面有10个物流方式&#xff0c;这10个物流方式是这10个国家都有的&#xff0c;…

第二十一章 网络通信

21.1网络程序设计基础 21.1.1局域网与互联网 服务器是指提供信息的计算机程序&#xff0c;客户机是指请求信息的计算机程序。网络用于连接服务器与客户机&#xff0c;实现两者间的相互通信。 21.1.2网络协议 1. IP协议 IP是Internet Protocol的简称。 TCP/IP模式是一种层…

Ubuntu18.04 本地安装CVAT标注工具

写在前面&#xff1a; 1、如果直接clone最新版本的cvat&#xff0c;python版本最好安装3.8的&#xff0c;因为其中部分代码的语法只有高版本的python才可以支持。 2、安装完成以后本地登陆可能出现"cannot connect to cvat server"的错误&#xff0c;可以从Cannot …

使用求2个字符串最短编辑距离动态规划算法实现 git diff 算法 java 实现

测试类 MyDiffTest.java&#xff1a; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.List;public class MyDiffTest {private static String path "\\xxx\\";private static List<String> lines…

【PUSDN】SpringBoot的jar进行解压后,替换其中的文件重新生成新的jar-SW

当你解压Spring Boot的JAR文件时&#xff0c;实际上是在打开一个压缩文件&#xff0c;类似于ZIP。你可以按照以下步骤进行替换文件并重新生成新的JAR&#xff1a; 解压原始的JAR文件&#xff1a; 使用任何ZIP工具&#xff08;如WinRAR、7-Zip或命令行工具&#xff09;&#xf…

[论文精读]序列建模使大视觉模型的规模化学习成为可能

本博客是一篇最新论文的精读&#xff0c;论文为UC伯克利大学及约翰霍普金斯大学相关研究者新近(2023.12.1)在arxiv上上传的《Sequential Modeling Enables Scalable Learning for Large Vision Models》 。知名科技新媒体“新智元”给与本文极高评价&#xff0c;并以《计算机视…

Linux(统信UOS) 发布.Net Core,并开启Https,绑定证书

实际开发中&#xff0c;有时会需要为小程序或者需要使用https的应用提供API接口服务&#xff0c;这就需要为.Net Core 配置https&#xff0c;配置起来很简单&#xff0c;只需要在配置文件appsettings.json中添加下面的内容即可 "Kestrel": {"Endpoints": …

一文带你了解云计算的未来发展趋势与优势

试问现在IT圈还有什么技术比较火&#xff1f;云在数字世界中扮演一个非常重要的角色&#xff0c;目前云计算还不算技术“红海”&#xff0c;它正处于高速发展前期的技术领域&#xff0c;现在早早转型过去&#xff0c;可能还能赶上一波技术红利&#xff0c;连目前大火的ChatGPT …

STM32-新建工程(标准库)

目录 STM32F10x新建工程&#xff08;标准库&#xff09; 移植文件夹 新建工程 添加启动文件和必需文件 在工程中加载新添加的文件 在工程中添加文件路径 在工程中添加main函数 添加lib库 添加必需文件 添加宏定义 点亮LED&#xff08;标准库&#xff09; STM32F10x新…

力扣题:字符的统计-12.4

力扣题-12.4 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;657. 机器人能否返回原点 解题思想&#xff1a;进行统计即可 class Solution(object):def judgeCircle(self, moves):""":type moves: str:rtype: bool""&qu…

安装获取mongodb

目录 本地安装 获取云上资源 获取Atlas免费数据库 本地连接数据库 在Atlas中连接数据库 本文适合初学者或mongodb感兴趣的同学来准备学习测试环境&#xff0c;或本地临时开发环境。mongodb是一个对用户非常友好的数据库。这种友好&#xff0c;不仅仅体现在灵活的数据结构和…

pre标签展示代码块

pre样式 添加背景色、边框、以及调整了字体大小。 pre { border: 1px solid #999; page-break-inside: avoid; display: block; padding: 3px 3px 2px; margin: 0 0 10px; font-size: 13px; line-height: 20px; word-break: break-all; word-wrap: break-word; /* white-space:…

​HTML代码混淆技术:原理、应用和实现方法详解

​HTML代码混淆技术&#xff1a;原理、应用和实现方法详解 HTML代码混淆是一种常用的反爬虫技术&#xff0c;它可以有效地防止爬虫对网站数据的抓取。本文将详细介绍HTML代码混淆技术的原理、应用以及实现方法&#xff0c;帮助大家更好地了解和运用这一技术。 一、HTML代码混淆…

HarmonyOS学习--初次下载安装和配置环境

一、Windows下载与安装软件 运行环境要求&#xff1a; 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff1a; 操作系统&#xff1a;Windows10 64位、Windows11 64位内存&#xff1a;8GB及以上硬盘&#xff1a;100GB及以上分辨率&#xff1a;1280*80…

springBoot3.2 + jdk21 + GraalVM上手体验

springBoot3.2 jdk21 GraalVM上手体验 SpringBoot2.x官方已经停止维护了&#xff0c;jdk8这次真的得换了&#x1f923; 可以参考官方文章进行体验&#xff1a;https://spring.io/blog/2023/09/09/all-together-now-spring-boot-3-2-graalvm-native-images-java-21-and-virt…

行云海CMS SQL注入漏洞复现

0x01 产品简介 行云海cms是完全开源的一套CMS内容管理系统,简洁,易用,安全,稳定,免费。 0x02 漏洞概述 行云海cms中ThinkPHP在处理order by排序时可利用key构造SQL语句进行注入,LtController.class.php中发现传入了orderby未进行过滤导致sql注入。攻击者除了可以利用 SQL 注入…