【动态规划上分复盘】这是你熟悉的地下城游戏吗?

欢迎

  • 前言
  • 一、动态规划五步曲
  • 二、地下城游戏
    • 题目分析
    • 思路:动态规划
      • 具体代码如下
  • 总结


前言

本文讲解关于动态规划思路的两道题目。


一、动态规划五步曲

  • 1.确定状态表示(确定dp数组的含义)
  • 2.确定状态转移方程(确定dp的递推公式)
  • 3.确定如何初始化(初始化要保证填表正确)
  • 4.确定遍历顺序
  • 5.返回值

二、地下城游戏

点我直达~
在这里插入图片描述

题目分析

根据题目可知,每一个位置都对应这三种情况:
(d[i][j]由题目给出。)

  • 1.d[i][j] < 0 :该位置有恶魔,骑士打败恶魔会掉血。
  • 2.d[i][j] = 0 :该位置是一条过道,不消耗血量。
  • 3.d[i][j] > 0 :该位置有一个血包,吃了血包可以加血。

我们知道,到达某个位置必须保证骑士血量大于1,否则就算该位置是一个大血包,骑士也享受不到。

思路:动态规划

  • 1.状态表示(确定dp数组的含义)
    每一道dp题的第一点往往是最重要的, 我们需要根据经验+题目要求来确定。
    一般来说,根据经验,确定状态表示有两种:

(1)以[i,j]位置为终点,…
(2)以[i,j]位置为起点,…

写了众多dp题,大部分题型是以[i,j]位置为终点,…,所以我们先看第一种情况:

    • (1)dp[i][j]表示:从起点出发,到达以[i,j]位置为终点时,所需要的最低健康值为dp[i][j].
      那么来看第二步,如何确定递推公式呢?
      请看下图:
      在这里插入图片描述
      以该图[i,j]位置为例,到达该位置一定是由上方走来或者左侧走来,所以我们需要考虑上方和左方的两种情况。
      根据题目意思,到达任意一个位置所需要的最低血量最少是1。
      所以我们不仅需要考虑当前位置,还需要考虑上方位置,左方位置,那么到达上方位置又需要进一步考虑,也就是说:到达[i,j]位置需要考虑其之前的所有的位置。并且到达[i,j]位置之后,如果未到达公主所在位置,我们仍然需要考虑后面的位置。并且初始的位置也是题目所要求我们求的,所以这个状态表示行不通。
      来看第二种。
    • (2)dp[i][j]表示:从[i,j]位置出发,到达终点时,所需要的最低健康值为dp[i][j].
      这样就可以行得通了。
      我们只需要考虑它的右方和下方位置即可。
  • 2.状态转移方程(确定递推公式)
    根据状态表示,和题目描述,我们知道[i,j]位置的下一步一定是走到[i+1,j] 或者[i,j+1]位置上的。所以我们应该考虑这三者之间的关系。
    我们知道,骑士到达任意一个位置,要求的最低血量必须大于等于1。
    所以我们从[i,j]位置出发,走到[i+1,j] 或者[i,j+1]位置上之后,在两个位置的任意一个中,血量必须大于等于1。否则就算该位置有大血包,骑士也无法享受。
    那么我们在考虑走到下一步时,应该先考虑自己位置上的值,应该+d[i][j],那么走到下一个位置的话,当前位置的最低健康点数必须大于等于下一个位置的最低健康点数,这样才能保证我们顺利走到下一个位置。
    所以递推公式如下:
    dp[i][j] + d[i][j] >= dp[i+1][j]dp[i][j] + d[i][j] >= dp[i][j+1]
    进行一下移项,得:
    dp[i][j] >= dp[i+1][j] - d[i][j]dp[i][j] >= dp[i][j+1] - d[i][j]
    由于要求最小的健康值,则当等于号成立时,就是最低的健康点数了:
    dp[i][j] = min(dp[i][j+1],dp[i+1][j]) - d[i][j]

但是有一个需要注意的点,当d[i][j]是一个非常大的数时,可能会导致减了d[i][j]之后,dp[i][j]是一个非正整数了,则表示骑士走到[i,j]位置是挂了的状态,并且还能吃了当前位置的血包顺利走到下一个位置,这显然是不符合逻辑的。
所以当dp[i,j]是一个非正整数时,所要求能通过当前位置的最低健康值就是1。
即dp[i][j] = max(1,dp[i][j])

代码如下:

dp[i][j] = min(dp[i-1][j],dp[i][j-1]) - d[i][j];
dp[i][j] = max(1,dp[i][j]);
  • 3.确定如何进行初始化
    上面分析了那么久,我们大概知道当骑士从公主所在位置出发到达公主所在位置时,即:
    在这里插入图片描述
    需要知道[i+1,j]位置和[i,j+1]位置。
    所以我们在初始化时,需要多开一行一列的虚拟空间,来更好地进行初始化。具体如下图:
    在这里插入图片描述

此时我们需要注意的点是:
虚拟空间的初始化必须保证不能影响正常结果。
在之前写的dp题目中,虚拟空间还需要注意第二点:
下标的映射关系,在这道题中,不需要注意,因为虚拟的空间并没有影响下标。
所以dp[m][n+1] 和dp[m+1][n]位置应该初始化成1,因为走到那个位置,最低健康值必须大于等于1,所以最小值为1。则其他位置根据以往经验,要保证不影响其他值,需要初始化成正无穷大。

  • 4.遍历顺序
    应该从下往上遍历,每行从右往左遍历。

  • 5.返回值
    返回dp[0][0]的值。

具体代码如下

class Solution {
public:int calculateMinimumHP(vector<vector<int>>& d) {//1.确定dp数组的含义//dp[i,j]表示:以[i,j]位置为起点,到达终点位置所需要的最小健康点数为dp[i][j]//2.确定递推公式    //dp[i][j] = min(dp[i+1][j],dp[i][j+1]) - d[i][j]//但是有可能算出来是非正整数,意味着走到这个位置已经是死了的状态,不符合题目要求。所以如果是非正整数的话,必须最小健康点数为1.//dp[i][j] = max(1,dp[i][j]);   //3.确定如何初始化//由于dp数组的含义是以[i,j]位置为起点的,所以我们必须从终点位置开始初始化,那么应该多开一行一列的虚拟空间来更好地初始化。//注意:1.虚拟空间的初始化不能影响结果。//这道题不同于之前的题,这里无需再注意下标的映射关系//4.遍历顺序(从下到上遍历,每行从右往左遍历)//5.返回值//dp[0][0]int m = d.size();int n = d[0].size();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][j+1],dp[i+1][j]) - d[i][j];//如果dp[i][j] <=0 ,则必须保证到[i,j]位置最低血量为1dp[i][j] = max(1,dp[i][j]);}}return dp[0][0];//时空复杂度O(m*n)}
};

时间复杂度O(m*n),空间复杂度O(m*n)

总结

今天写了一道困难题目,又学到了一种新的dp题型。

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

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

相关文章

Python中pyecharts模块

pyecharts模块 官网&#xff1a;pyecharts官网 pyecharts框架画廊 如果想要做出数据可视化效果图, 可以借助pyecharts模块来完成概况 : Echarts 是个由百度开源的数据可视化&#xff0c;凭借着良好的交互性&#xff0c;精巧的图表设计&#xff0c;得到了众多开发者的认可. 而…

巅峰极客2023 hellosql

随便输一个payload&#xff0c;有waf 这题只有两个回显&#xff0c;分别是太酷啦和nonono&#xff0c;不显示报错、登录成功等各种信息&#xff0c;目前只能想到用时间盲注。 抓包fuzz&#xff0c;194都是被过滤的 不止这些&#xff0c;手工测出来if、sleep、benchmark、*、rp…

办公室安全升级,如何保障人身财产安全?

视频监控&#xff0c;一种常见的安全措施&#xff0c;以监视和记录办公室内的活动。这项技术为企业提供了许多优势&#xff0c;包括保障员工和财产安全、帮助调查犯罪事件、提高业务管理效率以及应对突发事件。 因此&#xff0c;在合理范围内应用视频监控&#xff0c;将为企业提…

SAP从放弃到入门系列之批次派生-Batch Derivation-Part1

文章目录 一、概述二、系统配置三、主数据3.1 分类主数据3.2 派生规则设置3.2.1发送物料3.2.2 接收物料 四、 测试数据&#xff08;生产订单&#xff09;五、 最后 Batch Derivation翻译成批次派生&#xff08;衍生&#xff09;或批次继承都是问题不大&#xff0c;继承和派生个…

(学习笔记-IP)Ping的工作原理

Ping是基于ICMP协议工作的&#xff0c;ICMP报文封装在IP包里面&#xff0c;它工作在网络层&#xff0c;是IP协议的助手。 ICMP包头的类型字段&#xff0c;大致可分为两大类&#xff1a; 一类是用于诊断的查询消息&#xff0c;也就是查询报文类型一类是通知出错原因的错误消息&…

Spring 的元注解

一、元注解介绍 1.1.源码引入 1.2.元注解介绍 从上面的图片可知&#xff0c;Spring 有四个【负责注解其他注解】的元注解&#xff0c;分别是&#xff1a; Target&#xff1a;标识该注解可以用于标注哪些程序元素&#xff0c;比如类、方法、字段等。 Retention&#xff1a;标…

Zabbix-server监控mysql及httpd服务

目录 一、Zabbix监控mysql数据库 1、为server.Zabbix.com添加服务模板 2、创建mysql服务图形 二、server.zabbix.com服务器操作 编辑chk_mysql.sh脚本 三、server.Zabbix.com测试 四、查看web效果 五、Zabbix监控apache&#xff08;httpd服务&#xff09; 安装master 六、…

C++ 提高编程

C 提高编程 主要针对C泛型编程和STL技术 一、 模板 1、 概念 模板就是建立通用的模具&#xff0c;大大提高代码的复用性 模板特点 模板不可以直接使用&#xff0c;它只是一个框架 ​ 模板的通用并不是万能的 2、 函数模板 C 另一种编程思想为泛型编程&#xff0c;主要利用的…

Ubuntu搭建Samba服务-学习记录

文章目录 Ubuntu安装Samba流程Samba配置文件Samba添加账户配置文件修改Samba服务控制设置开机自动启动通过systemctl 启动服务通过 rc.local 启动 Windows访问参考链接 当前文章仅用于记录&#xff0c;在 Ubuntu中安装使用Samba&#xff0c;在Windows访问 系统环境&#xff1a;…

【问题记录】Ubuntu 22.04 环境下,程序报:段错误(核心已转储)怎么使用 core 文件和GDB调试器 解决?

目录 环境 问题情况 解决思路 原因分析 解决方法 番外知识 环境 VMware Workstation 16 Pro &#xff08;版本&#xff1a;16.1.2 build-17966106&#xff09;ubuntu-22.04.2-desktop-amd64 问题情况 本人在运行百万并发的服务端程序时&#xff0c;程序运行报&#xff1a…

VLAN---虚拟局域网

VLAN— 虚拟局域网 LAN—局域网 MAN—城域网 WAN—广域网 1.一个VLAN相当于是一个广播域 VLAN—通过路由器和交换机协同工作后&#xff0c;将原本的一个广播域逻辑上&#xff0c;拆 分为多个虚拟的广播域。 VLAN配置&#xff1a; 1.创建VLAN VID—VLAN ID------用来区分和…

浅谈能源管理系统在水泥行业中设计分析

安科瑞 华楠 摘要&#xff1a;水泥企业作为我国产业结构中重要的耗能产业&#xff0c;同时对环境的污染也比较大&#xff0c;因此在水泥企业中建立能源管理系统&#xff0c;对水泥企业的生产过程过程进行全过程的监控和管理&#xff0c;对于降低企业的能源消耗和提高企业的经济…

【Ajax】笔记-Axios与函数发送AJAX请求

Axios 和 Ajax 的区别 1、Axios是一个基于Promise的HTTP库&#xff0c;而Ajax是对原生XHR的封装&#xff1b; 2、Ajax技术实现了局部数据的刷新&#xff0c;而Axios实现了对ajax的封装。 优缺点&#xff1a; ajax&#xff1a; 本身是针对MVC的编程,不符合现在前端MVVM的浪潮 基…

【MySQL】之复合查询

【MySQL】之复合查询 基本查询多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使用子查询 合并查询小练习 基本查询 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的J按照部门号升序而雇员的工资降序排序使用…

性能测试Ⅱ(压力测试与负载测试详解)

协议 性能理论&#xff1a;并发编程 &#xff0c;系统调度&#xff0c;调度算法 监控 压力测试与负载测试的区别是什么&#xff1f; 负载测试 在被测系统上持续不断的增加压力&#xff0c;直到性能指标(响应时间等)超过预定指标或者某种资源(CPU&内存)使用已达到饱和状…

全志F1C200S嵌入式驱动开发(解决spi加载过慢的问题)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 之前的几个章节当中,我们陆续解决了spi-nor驱动的问题、uboot支持spi-nor的问题。按道理来说,下面要做的应该就是用uboot的loady命令把kernel、dtb、rootfs这些文件下载到ddr,然…

WebRTC Simulcast介绍

原文地址&#x1f447; https://blog.livekit.io/an-introduction-to-webrtc-simulcast-6c5f1f6402eb/ 你想知道的关于Simulcast的一切 Simulcast是WebRTC中最酷的功能之一,它允许WebRTC会议在参与者网络连接不可预测的情况下进行扩展。在这篇文章中,我们将深入探讨Simulcas…

欧姆龙CX系列PLC串口转以太网欧姆龙cp1hplc以太网连接电脑

你是否还在为工厂设备信息采集困难而烦恼&#xff1f;捷米特JM-ETH-CX转以太网通讯处理器为你解决这个问题&#xff01; 捷米特JM-ETH-CX转以太网通讯处理器专门为满足工厂设备信息化需求而设计&#xff0c;可以用于欧姆龙多个系列PLC的太网数据采集&#xff0c;非常方便构建生…

4、非线性数据结构

上一节课我们讲了线性数据结构&#xff0c;这一节我们说下非线性数据结构。 非线性数据结构&#xff0c;从字面意思来看&#xff0c;就是指不是线性的结构。线性结构的特点是只有一个前驱和一个后继。 那么非线性结构的特点就是有多个前驱或后继了。 如果只存在一个没有前驱的…

ChatGPT是什么?ChatGPT里的G、P、T分别指什么

前言 ChatGPT是一种基于人工智能技术的聊天机器人&#xff0c;它可以模拟人们的对话方式进行自然语言交流&#xff0c;并根据用户提出的问题、需求、意愿等信息提供相关服务或回答问题。 ChatGPT的G、P、T分别指“生成式”&#xff08;Generative&#xff09;、“预训练”&…