蓝桥杯刷题_day7_动态规划_路径问题

文章目录

  • DAY7
    • 下降路径最小和
    • 最小路径和
    • 地下城游戏

DAY7

下降路径最小和

【题目描述】
给你一个 n x n方形 整数数组 matrix ,请你找出并返回通过 matrix下降路径最小和

下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)(row + 1, col) 或者 (row + 1, col + 1)

【输入样例】

matrix = [[2,1,3],[6,5,4],[7,8,9]]

【输出样例】

13

【数据规模与约定】

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 100
  • -100 <= matrix[i][j] <= 100

【解题思路】

【C++程序代码】

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        int n = matrix.size();

        vector<vector<int> > dp(n, vector<int>(n + 2, INT_MAX));
        for (int i = 0; i < n; i++)
        {
            dp[i][0] = 100;
            dp[i][n+1] = 100;
        }
        for (int i = 1; i <= n; i++)
        {
            dp[0][i] = matrix[0][i - 1];
        }

        for (int i = 1; i < n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                dp[i][j] = matrix[i][j - 1] + min({ dp[i - 1][j - 1],dp[i - 1][j],dp[i - 1][j + 1] });
            }
        }
        int min_num = INT_MAX;
        for (int i = 0; i <= n; i++)
        {
            min_num = min(min_num, dp[n - 1][i]);
        }
        return min_num;
    }
};

最小路径和

【题目描述】
给定一个包含非负整数的 _m_ x _n_ 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

【输入样例】

grid = [[1,3,1],[1,5,1],[4,2,1]]

【输出样例】

7

【数据规模与约定】

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 200

【解题思路】
通过题目得出dp[i]表示的是走到当前位置时的最小路径和。由因为题目要求只能向下或者向右走一步,所以dp[i]应该是上面的格子或者右边的格子其中小的那个加上当前位置的值。

【C++程序代码】

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int row = grid.size();
        int col = grid[0].size();

        vector<vector<int> > dp(row + 1, vector<int>(col + 1,INT_MAX));
        dp[0][1] = 0;
        dp[1][0] = 0;
        for (int i = 1; i <= row; i++)
        {
            for (int j = 1; j <= col; j++)
            {
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
            }
        }

        return dp[row][col];
    }
};

地下城游戏

【题目描述】
恶魔们抓住了公主并将她关在了地下城 dungeon右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。

骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。

有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为_负整数_,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为_正整数_,则表示骑士将增加健康点数)。

为了尽快解救公主,骑士决定每次只 向右向下 移动一步。

返回确保骑士能够拯救到公主所需的最低初始健康点数。

注意: 任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

【输入样例】

dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]]


【输出样例】

7

【数据规模与约定】

  • m == dungeon.length
  • n == dungeon[i].length
  • 1 <= m, n <= 200
  • -1000 <= dungeon[i][j] <= 1000

【解题思路】
这个问题是一个典型的动态规划问题。我们需要找到英勇骑士拯救公主时所需的最低初始健康点数。为了解决这个问题,我们可以从终点开始(即公主所在的右下角),逆向思考骑士到达每个房间所需的最低健康点数。这样,我们可以确保骑士在任何时刻的健康点数都不会低于1。

  1. 动态规划状态定义
    我们定义 dp[i][j] 为从点 (i, j) 到达终点所需的最低健康点数。因此,dp[0][0] 就是我们要找的答案。

  2. 边界条件

    1. dp[m-1][n-1]:这是公主所在的房间,骑士至少需要1点健康,如果这个房间的值为正,则骑士只需要1点健康即可;如果为负,则骑士需要足够的健康点数以确保他在离开这个房间时至少有1点健康。因此,dp[m-1][n-1] = max(1, 1 - dungeon[m-1][n-1])
    2. 边界的其他点:对于最下面一行(row)和最右边一列(col),骑士只能向右或者向下移动,因此每个点的 dp 值依赖于它右边或者下面的点的 dp 值。
  3. 状态转移方程
    对于非边界点 (i, j),骑士可以从 (i+1, j)(下方)或 (i, j+1)(右方)到达 (i, j)。因此,dp[i][j] 依赖于 dp[i+1][j]dp[i][j+1]。骑士在 (i, j) 点的健康点数必须足以让他能够到达 (i+1, j) 或 (i, j+1),同时保持至少1点健康。因此,状态转移方程为:
    dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j])
    这里 max(1, x) 确保了在任何时刻骑士的健康点数至少为1。

  4. 计算顺序
    由于我们从终点开始反向计算,所以我们应该从右下角开始,首先计算最后一行和最后一列,然后向左上方移动,直到计算到 dp[0][0]

  5. 实现细节

    1. 初始化 dp 数组,除了 dp[row-1][col-1] 之外,其他所有 dp[row][col] 均设为 INT_MAX。
    2. 从右下角开始逆向遍历,计算每个 dp[i][j]
    3. 返回 dp[0][0] 作为结果。

【C++程序代码】

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int row = dungeon.size();
        int col = dungeon[0].size();

        vector<vector<int>> dp(row + 1, vector<int>(col + 1,INT_MAX));
        dp[row][col - 1] = dp[row - 1][col] = 1;

        for (int i = row - 1; i >= 0; i--)
        {
            for (int j = col - 1; j >= 0; j--)
            {
                dp[i][j] = min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j];
                dp[i][j] = max(dp[i][j], 1);
            }
        }
        return dp[0][0];
    }
};

代码详解

在这段代码中,我们初始化了一个 (row + 1) x (col + 1) 大小的 dp 数组,并将除 dp[row][col - 1] 和 dp[row - 1][col] 外的所有元素设置为 INT_MAX,这样做是为了确保在逆向计算过程中,我们不会用到这些未初始化的状态值。
然后我们从 dp[row - 1][col - 1] (即公主所在的房间)开始向左上方逆向遍历,对每一个格子 (i, j),计算所需的最小初始健康点数。这个数值是根据它的右边 (i, j+1) 和下边 (i+1, j) 的两个格子的 dp 值来得到的。我们取这两个 dp 值中较小的一个,然后减去当前格子的 dungeon[i][j] 值(如果当前格子是恶魔,dungeon[i][j] 将是负数;如果是魔法球或空房间,dungeon[i][j] 将是非负数),以此来计算骑士在进入格子 (i, j) 前,所需的最小健康点数。最后,我们需要确保这个数值至少为1,因为骑士的健康点数不能少于1。
最终,dp[0][0] 就是我们要找的答案,即骑士从左上角出发所需的最小初始健康点数。

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

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

相关文章

基于Websocket的局域网聊天系统

1.1 研究背景及意义 本项目所对应领域的研究背景及意义[1]。新冠肺炎局域网通信发生以来&#xff0c;大数据、云计算、人工智能等新一代信息技术加速与交通、局域网通信、教育、金融等领域深度融合&#xff0c;让局域网通信防控的组织和执行更加高效&#xff0c;成为战“疫”的…

C++王牌结构hash:哈希表开散列(哈希桶)的实现与应用

目录 一、开散列的概念 1.1开散列与闭散列比较 二、开散列/哈希桶的实现 2.1开散列实现 哈希函数的模板构造 哈希表节点构造 开散列增容 插入数据 2.2代码实现 一、开散列的概念 开散列法又叫链地址法(开链法)&#xff0c;首先对关键码集合用散列函数计算散列地址&…

Day57:WEB攻防-SSRF服务端请求Gopher伪协议无回显利用黑白盒挖掘业务功能点

目录 SSRF-原理&挖掘&利用&修复 SSRF无回显解决办法 SSRF漏洞挖掘 SSRF协议利用 http:// &#xff08;常用&#xff09; file:/// &#xff08;常用&#xff09; dict:// &#xff08;常用&#xff09; sftp:// ldap:// tftp:// gopher:// &#xff08;…

使用AOP实现打印日志

首先创建annotation.SystemLog类&#xff1a; package com.gjh.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;Target(ElementType.METHOD…

深度学习pytorch——nn.Module(持续更新)

作为一个初学者&#xff0c;发现构建一个简单的线性模型都能看到nn.Module的身影&#xff0c;初学者疑惑了&#xff0c;nn.Module到底是干什么的&#xff0c;如此形影不离&#xff0c;了解之后&#xff0c;很牛。 1、nn.Module是所有层的父类&#xff0c;比如Linear、BatchNor…

Bun安装与使用

Bun安装与使用。 它目前无法在windows上直接安装使用&#xff0c;必须通过虚拟机安装。 在win10虚拟机中安装 # 查看内核版本 $ uname -srm Linux 6.1.0-10-amd64 x86_64# 安装unzip解压工具 $ sudo apt install unzip# 下载安装脚本并开始安装 curl -fsSL https://bun.sh/ins…

C#使用SQLite(含加密)保姆级教程

C#使用SQLite 文章目录 C#使用SQLite涉及框架及库复制runtimes创建加密SQLite文件生成连接字串执行SQL生成表SQLiteConnectionFactory.cs 代码结构最后 涉及框架及库 自己在NuGet管理器里面安装即可 Chloe.SQLite&#xff1a;ORM框架Microsoft.Data.Sqlite.Core&#xff1a;驱…

3.Python数据分析—数据分析入门知识图谱索引(知识体系中篇)

3.Python数据分析—数据分析入门知识图谱&索引-知识体系中篇 一个人简介二数据获取和处理2.1 数据来源&#xff1a;2.2 数据清洗&#xff1a;2.2.1 缺失值处理&#xff1a;2.2.2 异常值处理&#xff1a; 2.3 数据转换&#xff1a;2.3.1 数据类型转换&#xff1a;2.3.2 数据…

【unity】解决unity编译器安装中文汉化包失败

如果有的同学中文包安装失败&#xff0c;我们找到相应的编译器版本&#xff0c;点击在资源管理器中显示按钮&#xff0c; 我们点击当前目录的上一级&#xff0c;进入编译器目录。 找到modules.json文件双击打开 我们找到简体中文&#xff0c;复制downloadUrl后面的值到浏览…

Spark SQL— Catalyst 优化器

Spark SQL— Catalyst 优化器 1. 目的 本文的目标是描述Spark SQL 优化框架以及它如何允许开发人员用很少的代码行表达复杂的查询转换。我们还将描述Spark SQL如何通过大幅提高其查询优化能力来提高查询的执行时间。在本教程中&#xff0c;我们还将介绍什么是优化、为什么使用…

K8S安装和部署(kubeadmin安装1主2从)

这里用kubeadmin方式进行安装部署 1. 准备三台服务器 服务器地址 节点名称 192.168.190.200 master 主 192.168.190.201 node1 从 192.168.190.202 node2 从 2. 主机初始化&#xff08;所有主机&#xff09; 2.1根据规划设置主机名 #切换到192.168.190.200 hostnamectl…

【C++的奇迹之旅】C++关键字命名空间使用的三种方式C++输入输出命名空间std的使用惯例

文章目录 &#x1f4dd;前言&#x1f320; C关键字(C98)&#x1f309; 命名空间&#x1f320;命名空间定义&#x1f309;命名空间使用 &#x1f320;命名空间的使用有三种方式&#xff1a;&#x1f309;加命名空间名称及作用域限定符&#x1f320;使用using将命名空间中某个成员…

【Frida】【Android】06_夜神模拟器中间人抓包

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

如何更新STEAM税务信息

回复邮件 Here are three attachments:. Figure 1: My personal tax information file in the government system, including my TIN, permanent address and mailing address Figure 2. My tax payment certificate in China in 2002 was issued by the tax bureau, Figure 3:…

npm ERR! errno CERT_HAS_EXPIRED

1 问题描述 使用npm命令安装相关依赖报错&#xff1a;npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/vue%2fcli failed, reason: certificate has expired报错示例图如下所示&#xff1a; 2原因分析…

C语言循环结构的程序设计

在C语言中&#xff0c;循环结构是一种重要的控制结构&#xff0c;用于重复执行特定的代码块&#xff0c;直到满足特定的条件为止。循环结构使得程序可以更加灵活和高效地处理重复性的任务&#xff0c;从而提高了程序的可读性和可维护性。本文将深入介绍C语言中循环结构的程序设…

小型分布式文件存储系统GoFastDfs应用简介

前言 最近稍微留意了一下各个文件存储系统的协议&#xff0c;发现minio是LGPLV3, 而fastdfs 是GPL3,这些协议其实对于商业应用是一个大坑。故而寻找一些代替品。 go-fastdfs就是其中之一&#xff0c;官网在&#xff1a; go-fastdfs 具体应用 其实可以直接查看官网教程的。 下…

Jenkins详细安装配置部署

目录 简介一、安装jdk二、安装jenkins这里如果熟悉 Jenkins &#xff0c;可以【选择插件来安装】&#xff0c;如果不熟悉&#xff0c;还是按照推荐来吧。注意&#xff1a; 三、插件安装如果上面插件安装&#xff0c;选择的不是【安装推荐的插件】&#xff0c;而是【选择插件来安…

学习Fast-LIO系列代码中相关概念理解

目录 一、流形和流形空间&#xff08;姿态&#xff09; 1.1 定义 1.2 为什么要有流形? 1.3 流形要满足什么性质&#xff1f; (1) 拓扑同胚 (2) 可微结构 1.4 欧式空间和流形空间的区别和联系? (1) 区别&#xff1a; (2) 联系&#xff1a; 1.5 将姿态定义在流形上比…

基于java+springboot+vue实现的二手闲置物品置换系统(文末源码+Lw+ppt)23-375

摘 要 大学生二手闲置物品置换交易管理系统设计的目的是为用户提供免费物品、积分物品等功能。 与其它应用程序相比&#xff0c;大学生二手闲置物品置换交易的设计主要面向于学校&#xff0c;旨在为管理员和卖家、用户提供一个大学生二手闲置物品置换交易管理系统。用户可以…
最新文章