【动态规划】【 矩阵】【逆向思考】C++算法174地下城游戏

作者推荐

【动态规划】【字符串】扰乱字符串

本文涉及的基础知识点

动态规划 矩阵 逆向思考

LeetCode174地下城游戏

恶魔们抓住了公主并将她关在了地下城 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

正向思考

每个单格需要记录如下信息:a,从起点到当前点增加(消耗)的健康。b,整个路径的最小健康(最大消耗)。
两种信息的最大可能2m+n ,其实信息b 只有n+m种可能,我们记录最小健康所在单格。r,c,b 确定的情况下:a越大越好。
这样有nmnm种状态。空间复杂度是:O(nnmm)
每种状态的转移时间复杂度是O(nm)。
总时间复杂度O(nnnmmm),铁定超时

逆向动态规范

能够进入dungeon[r][c]的两个条件:
一,dp[r][c] >=1
二,dp[r][c] + dungeon[r][c]>=1 ===>>>> dp[r][c] >= 1 = dungeon[r][c]
非终点格还需要符合三或符合四。
三,dp[r][c] + dungeon[r][c] >= dp[r+1][c]
四,dp[r][c] + dungeon[r][c] >= dp[r][c+1]
由于dp[r+1][c]和dp[r][c+1]必定>=1 ,所以非终点格条件二可以省略。

动态规划的状态表示dp[r][c]表示进入当前单格需要的最小健康度
动态规划的转移方程能进入当前单格,能进入右边或下边的格子
动态规划的初始状态dp[r-1][c-1]=max(1,1-dungeon [r-1][c-1]
动态规划的填表顺序r c都从大到小处理,确保动态规划的无后效性
动态规划的返回值dp[0][0]

代码

核心代码

class Solution {
public:
	int calculateMinimumHP(vector<vector<int>>& dungeon) {
		m_r = dungeon.size();
		m_c = dungeon.front().size();
		vector<vector<int>> dp(m_r, vector<int>(m_c, INT_MAX));
		dp.back().back() = max(1, 1 - dungeon.back().back());
		for (int r = m_r - 1; r >= 0; r--)
		{
			for (int c = m_c - 1; c >= 0; c--)
			{
				if (r+1 < m_r)
				{		
					dp[r][c] = min(dp[r][c], dp[r + 1][c] - dungeon[r][c]);
				}
				if (c+1 < m_c)
				{
					dp[r][c] = min(dp[r][c], dp[r][c+1] - dungeon[r][c]);
				}
				dp[r][c] = max(1, dp[r][c]);
			}
		}
		return dp[0][0];
	}
	int m_r, m_c;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}
}


int main()
{
	vector<vector<int>> dungeon;
	{
		Solution sln;
		dungeon = { {0} };
		auto res = sln.calculateMinimumHP(dungeon);
		Assert(1, res);
	}
	{
		Solution sln;
		dungeon = { {-2,-3,3},{-5,-10,1} };
		auto res = sln.calculateMinimumHP(dungeon);
		Assert(6, res);
	}
	{
		Solution sln;
		dungeon = { {-2,-3,3},{-5,-10,1},{10,30,-5} };
		auto res = sln.calculateMinimumHP(dungeon);
		Assert(7, res);
	}
	
}

2023年1月版

class Solution {
public:
int calculateMinimumHP(vector<vector>& dungeon) {
m_r = dungeon.size();
m_c = dungeon[0].size();
vector<vector> dp;
dp.assign(m_r, vector(m_c, INT_MAX));
//不考虑候选,进入本格的最小值
for (int r = m_r - 1; r >= 0; r–)
{
for (int c = m_c - 1; c >= 0; c–)
{
dp[r][c] = (dungeon[r][c] > 0) ? 1 : (1 - dungeon[r][c]);
}
}
for (int r = m_r - 1; r >= 0; r–)
{
for (int c = m_c - 1; c >= 0; c–)
{
int tmp = INT_MAX;
if (c + 1 < m_c)
{//可以右移
tmp = min(tmp,dp[r][c + 1] - dungeon[r][c]);
}
if (r + 1 < m_r)
{
tmp = min(tmp, dp[r + 1][c] - dungeon[r][c]);
}
if (INT_MAX == tmp)
{
continue;
}
dp[r][c] = max(dp[r][c], tmp);
}
}
/*
if (r > 0)
{
dp[r - 1][c] = min(dp[r - 1][c],)
}*/
return dp[0][0];
}
int m_r, m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

Golang leetcode142 环形链表 暴力map 快慢指针法

文章目录 环形链表 leetcode142暴力遍历 map哈希记录快慢指针法 环形链表 leetcode142 该题目要求找到入环的第一个节点 我们可以通过map进行记录&#xff0c;没到新的节点查询是否经过原有节点 入环节点&#xff0c;上两个节点的next相同 若有入环节点&#xff0c;则一定能检…

TypeError: loaderUtils.getOptions is not a function

webpack 版本&#xff1a;^5.89.0 但是直接 pnpm add loader-utils 安装的版本比较新&#xff0c;会报错&#xff1a;TypeError: loaderUtils.getOptions is not a function。 解决方案&#xff1a;将低 loader-utils 版本&#xff0c;我这里使用 ^2.0.0 就不会再报这个错误了 …

【读书笔记】网空态势感知理论与模型(九)

对分析人员数据分类分流操作的研究 1.概述 本章节介绍一种以人员为中心的智能数据分类分流系统&#xff0c;该系统利用了入侵检测分析人员的认知轨迹。整合了3个维度的动态网络-人系统&#xff08;cyber-humber system&#xff09;&#xff1a;网空防御分析人员、网络监测数据…

muduo网络库剖析——网络地址InetAddress类

muduo网络库剖析——网络地址InetAddress类 前情从muduo到my_muduo 概要socketaddr_in介绍成员用法 网络地址转换函数 框架与细节成员函数使用方法 源码 前情 从muduo到my_muduo 作为一个宏大的、功能健全的muduo库&#xff0c;考虑的肯定是众多情况是否可以高效满足&#xf…

RocketMQ源码 发送顺序消息源码分析

前言 rocketmq 发送顺序消息和普通消息的主流程区别大部分一致的&#xff0c;区别在于&#xff1a;普通消息发送时&#xff0c;从所有broker的队列集合中 轮询选择一个队列&#xff0c;而顺序队列可以提供用户自定义消息队列选择器&#xff0c;从NameServer 分配的顺序 broker…

动态编译 - Dynamically Compile and Load External Java Classes

文章目录 概述Code 概述 动态编译和加载外部Java类的核心流程可以概括为以下几个步骤&#xff1a; 读取源代码: 首先&#xff0c;需要获取到外部的Java源代码。这通常是通过读取文件、网络资源或者数据库中的源代码字符串来实现的。编译源代码: 接下来&#xff0c;需要使用Ja…

PHP在线sqlite转html表格小功能(sqlite2html)

6KB PHP实现在线sqlite转html表格小功能(支持大文件上传,得到一表一文件) 可自定义&#xff1a;上传限制大小&#xff1b;支持后缀格式!下载格式位压缩包&#xff0c;内含一表一个html文件。 作用&#xff1a;程序员实用工具&#xff0c;上传sqlite数据得到html表格数据供本地…

[ESP32]如何透過Modbus和Serial port擷取工業數顯表頭資料?

[ESP32]ESP32 as Modbus Master and Receive Data from Gauge with Serial Port 對於既有老舊的工業或實驗設備機台&#xff0c;嵌入工業數顯表頭並顯示設備運作參數和數據&#xff0c;以讓巡檢人員或操作人員手抄記錄數據&#xff0c;是常見作法。然而&#xff0c;若可將既有設…

个人笔记:分布式大数据技术原理(一)Hadoop 框架

Apache Hadoop 软件库是一个框架&#xff0c;它允许使用简单的编程模型&#xff0c;实现跨计算机集群的大型数据集的分布式处理。它最初的设计目的是为了检测和处理应用程序层的故障&#xff0c;从单个机器扩展到数千台机器&#xff08;这些机器可以是廉价的&#xff09;&#…

环形缓冲区优点及实现

环形缓冲区优点及实现 目录 环形缓冲区优点及实现一、环形缓冲区概念二、环形缓冲区优点1、一个有缺陷的数据读写示例2、使用环形缓冲区解决数据读写缺陷 三、环形缓冲区实现代码 一、环形缓冲区概念 环形缓冲区是一种特殊的缓冲区&#xff0c;其读指针和写指针都指向同一个缓…

MySQL之视图索引执行计划

目录 一.视图 二.执行计划 2.1.什么是执行计划 2.2.执行计划的作用 三.使用外连接、内连接和子查询进行举例 四.思维导图 好啦今天就到这里了哦&#xff01;&#xff01;&#xff01;希望能帮到你哦&#xff01;&#xff01;&#xff01; 一.视图 含义 &#xff1a;在数…

【BIAI】lecture 3 - GD BP CNN Hands-on

GD & BP & CNN & Hands-on 专业术语 gradient descent (GD) 梯度下降 back propagation (BP) 向传播 Convolutional Neural Network (CNN) 卷积神经网络 forward propagation 前向传播 biologically symmetry 生物对称性 synaptic 突触 axon 轴突 课程大纲 The go…

webgl调试之排查内存泄漏

内存泄漏自然而然是要看内存是不是涨了 然后我们如何确认泄露了呢&#xff0c;我们需要把代码梳理清楚&#xff0c;知道哪个时机&#xff0c;在delete&#xff0c;在create&#xff0c;那么这个时候&#xff0c;按道理&#xff0c;delete了n个对象&#xff0c;create了N个对象&…

Redis 键中冒号的用途是什么?可以使匹配查询更快吗?

Redis 键中冒号的用途是什么在Redis中&#xff0c;冒号&#xff08;:&#xff09;用作键的分隔符&#xff0c;它的主要作用是创建层次结构和命名空间。通过在键中使用冒号&#xff0c;可以将键分为多个部分&#xff0c;从而更好地组织和管理数据。 以下是冒号在Redis键中的用途…

2024苹果Mac电脑免费文件数据恢复软件EasyRecovery

EasyRecovery是一个操作安全、价格便宜、用户自主操作的非破坏性的只读应用程序&#xff0c;它不会往源驱上写任何东西&#xff0c;也不会对源驱做任何改变&#xff01;EasyRecovery是一个操作安全、价格便宜、用户自主操作的非破坏性的只读应用程序&#xff0c;它不会往源驱上…

MySQL第四战:视图以及常见面试题(上)

目录 目录&#xff1a; 一.视图 1.介绍什么是视图 2.视图的语法 语法讲解 实例操作 二.MySQL面试题 1.SQL脚本 2.面试题实战 三.思维导图 目录&#xff1a; 随着数字化时代的飞速发展&#xff0c;数据库技术&#xff0c;特别是MySQL&#xff0c;已经成为IT领域中不可…

短网址的新玩法,短到只剩域名

短网址大家应该都不陌生了&#xff0c;一句话就可以解释清楚&#xff0c;把一串很长的网址缩短到只有几个字符依然可以正常访问&#xff0c;缩短之后会更加简洁美观。 那大家见过的短网址一般长啥样呢&#xff0c;比如t.cn/xxxxx、dwz.cn/xxxxx、c1ns.cn/xxxxx。这些短网址都有…

初始MySQL

一、数据库 1.什么是数据库 数据库&#xff08; Database,简称DB &#xff09;&#xff1a;长期存放在计算机内&#xff0c;有组织、可共享的大量数据的集合&#xff0c;是一个数据“仓库” 2.数据库的作用 可以结构化存储大量的数据&#xff0c;方便检索和访问保持数据信息…

JVM工作原理与实战(八):类加载器的分类

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、类加载器介绍 二、类加载器的分类 1.Java代码实现的类加载器 2.Java虚拟机底层源码实现的类加载器 3.默认的类加载器层次&#xff08;JDK8及之前的版本&#xff09; 总结 前言…

迅为RK3588开发板使用 FFMpeg 进行推流

Debian/Ubuntu 系统使用以下命令安装 FFMpeg &#xff0c;如下图所示&#xff1a; apt-get install ffmpeg 使用 ifconfig 查看开发板 ip 为 192.168.1.245 如下图所示&#xff1a; 使用 FFMpeg 推流一个 mp4 视频进行测试&#xff0c;作者将测试视频 test.mp4 放在了根目录下…