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

news2025/1/11 14:59:07

欢迎

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


前言

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


一、动态规划五步曲

  • 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]位置最低血量为1
                dp[i][j] = max(1,dp[i][j]);
            }
        }

        return dp[0][0];
        //时空复杂度O(m*n)
    }
};

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

总结

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

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

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

相关文章

NumPy实现逻辑回归

说明&#xff1a;数据集 ex2data1.txt是吴恩达机器学习的作业的数据集。 # -*-coding:utf-8-*- import matplotlib.pyplot as plt import numpy as np import pandas as pdclass Logitstic_Regression:def __init__(self, learning_rate0.01, num_iterations75000, threshold0.…

# 技术架构演进之路

技术架构演进之路 文章目录 技术架构演进之路单机架构应用数据分离架构应用服务集群架构读写分离架构冷热分离架构垂直分库架构微服务架构容器编排技术互联网架构 单机架构 简介应用和服务公用一台服务器出现原因出现在互联网早期,访问量比较小,单机足以满足需求.架构工作原理…

本地新项目推送至gitlab仓库

1. gitlab上新建一个空白项目 gitlab上点击new project按钮&#xff0c;新建一个项目 新建空白项目 项目名称与本地新建项目名称相同&#xff0c;其余根据具体需要选择 2. 初始化本地仓库并commit项目 进入本地项目根目录下&#xff0c;右击 git bash here打开命令窗口 初始化…

java代码审查过关的一次总结

**1.for循环中的逻辑都抽出一个方法并且把重要逻辑抽出一个方法 2.参数比较多合并成一个对象 3.避免没必要的if else 例如if判断能直接return就return,避免没必要的else 4.检查代码中是否包含适当的注释&#xff0c;解释代码的目的、实现细节和注意事项。 5.代码格式和命名规…

百炼智能发布垂直模型“爱迪生”,B2B行业的AIGC大潮来了

&#xff08;图片来源&#xff1a;Pixels&#xff09; AIGC终于来到B2B行业&#xff0c;企业服务AGI时代已拉开帷幕。 数科星球原创 作者丨苑晶 编辑丨大兔 百炼智能是一家专注B2B行业的智能营销企业。在过去&#xff0c;该行业经历了大数据、人工智能时代的洗礼。随着行业对数…

jupyter中如何管理内核

1、jupyter notebook如何和已有的虚拟环境关联起来&#xff1a; 如果在电脑中某个conda的虚拟环境中已经安装了jupyter&#xff0c;其他虚拟环境想要作为内核在jupyter中使用&#xff0c;分为两个步骤&#xff1a; 第一步&#xff1a;在没有jupyter的环境中下载ipykernel&…

E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

T&#xff1a;what Y&#xff1a;why W&#xff1a;how Y $ sudo apt-get install ros-noetic-gazebo-ros 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 有一些软件包无法被安装。如果您用的是 unstable 发行版&#xff0…

可信数据库大会,不见不散!

由中国信息通信研究院、中国通信标准化协会指导&#xff0c;中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;、InfoQ 极客传媒联合主办的 2023 可信数据库发展大会将于今日在北京国际会议中心隆重召开。 本届大会以“自主 创新 引领”为主题…

【线段树】P6492 [COCI2010-2011#6] STEP

P6492 [COCI2010-2011#6] STEP - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意&#xff1a; 思路&#xff1a; 要维护区间最长子串&#xff0c;就需要维护左起最长子串和右起最长子串 要维护这两者&#xff0c;就得维护区间两端的种类 Code&#xff1a; #include <…

Spark数据倾斜优化-AQE Skewed Join

AQE处理SkewedJoin的原理 Spark Adaptive Query Execution &#xff0c; 简称 Spark AQE&#xff0c;总体思想是动态优化和修改 stage 的物理执行计划。利用执行结束的上游 stage 的统计信息&#xff08;主要是数据量和记录数&#xff09;&#xff0c;来优化下游 stage 的物理…

记一次自建靶场域渗透过程

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 环境搭建02 外网突破03 权限提升并维持&#xff08;1&#xff09;获取 meterpreter 会话&#xff08;2&#xff09;尝试开启远程桌面&#xff08;3&#xff09;Msf 派生 Cobalt Strike shell&#…

TinyStories: How Small Can Language Models Be and Still Speak Coherent English?

本文是LLM系列的文章之一&#xff0c;针对《TinyStories: How Small Can Language Models Be and Still Speak Coherent English?》的翻译。 TinyStories&#xff1a;语言模型能有多小&#xff0c;还能说连贯的英语&#xff1f; 摘要1 引言2 TinyStories数据集的描述2.1 Tiny…

<td>标签内的文字内容换行显示

修改前&#xff1a; 修改后&#xff1a; 代码&#xff1a; table tr td{ word-WRAP: break-word }

CI-持续集成 — 软件工业“流水线”技术实现

1 概述 持续集成&#xff08;Continuous Integration&#xff09;是一种软件开发实践。在本系列文章的前一章节已经对其背景及理论体系进行了介绍。本小节则承接前面提出的理论构想进行具体的技术实现。 《Google软件测试之道》: "每天&#xff0c;Google都要测试和发…

(模拟) 463. 岛屿的周长 ——【Leetcode每日一题】

❓ 463. 岛屿的周长 难度&#xff1a;简单 给定一个 row x col 的二维网格地图 grid &#xff0c;其中&#xff1a;grid[i][j] 1 表示陆地&#xff0c;grid[i][j] 0 表示水域。 网格中的格子 水平和垂直 方向相连&#xff08;对角线方向不相连&#xff09;。整个网格被水完…

前端Vue自定义可自由滚动精美tabs选项卡标签栏标题栏 可设置背景颜色,

前端Vue自定义可自由滚动精美tabs选项卡标签栏标题栏 可设置背景颜色&#xff0c; 下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13313 效果图如下&#xff1a; # cc-scrollTag #### 使用方法 使用方法 <!-- tabChange: tab选…

Vue指令--v-bind、v-model、v-on

常见指令--v-bind/model/on 指令&#xff1a;HTML标签中带有v-前缀的特殊属性&#xff0c;不同指令具有不同含义。例如&#xff1a;v-if&#xff0c;v-for..常见指令 指令 作用 v-bind为HTML标签绑定属性值&#xff0c;如设置href、css样式等v-model在表单元素上创建双向数据…

【网络原理之二】网络层的IP协议、数据链路层的以太协议和MTU

网络层协议IP协议IP协议格式IP地址IPV4IPV6 IP地址规则-地址管理路由选择 数据链路层协议以太网协议协议格式 MTU(最大传输单元)MTU对IP协议的影响MTU对UDP协议的影响MTU对TCP协议的影响 开放性问题 网络层协议 IP协议 IP协议格式 4位版本号(version)&#xff1a;指定IP协议的…

12-Vue的diff算法

参考回答&#xff1a; 当组件创建和更新时&#xff0c;vue均会执行内部的update函数&#xff0c;该函数使用render函数生成的虚拟dom树&#xff0c;将新旧两树进行对比&#xff0c;找到差异点&#xff0c;最终更新到真实dom对比差异的过程叫diff&#xff0c;vue在内部通过一个叫…

ChatGPT系统源码,全开源支持二开!

ChatGPT是开发的大语言模型之一&#xff0c;具备多领域知识&#xff0c;并且可以提供个性化、准确和有趣的答案&#xff0c;无论是在娱乐、教育还是工作中&#xff0c;都可以帮助我们解决问题、获取信息和提供建议。 技术架构 使用流行的技术栈PHP8、TypeScript、ThinkPHP6、…