【动态规划】零基础解决路径问题(C++)

目录

62.路径问题

解法(动态规划):

1. 状态表⽰:

2. 状态转移⽅程:

3. 初始化:

4. 填表顺序:

5. 返回值:

不同路径2.0

解法(动态规划):

1. 状态表⽰:

2. 状态转移:

3. 初始化:

4. 填表顺序:

5. 返回值:

代码

剑指Offer47.礼物的最⼤价值

方程;

代码:

931.下降路径最小和

 代码:

64.最小路径和 

【困难题】 174.地下城游戏(视频讲解)

总结:


62.路径问题

解法(动态规划):

算法思路:

1. 状态表⽰:

对于这种「路径类」的问题,我们的状态表⽰⼀般有两种形式:

  • i. [i, j] 位置出发,巴拉巴拉;
  • ii. 从起始位置出发,到达[i, j] 位置,巴拉巴拉。

这⾥选择第⼆种定义状态表⽰的⽅式: dp[i][j] 表⽰:⾛到[i, j] 位置处,⼀共有多少种⽅式。

2. 状态转移⽅程:

简单分析⼀下。如果dp[i][j] 表⽰到达[i, j] 位置的⽅法数,那么到达[i, j] 位置之 前的⼀⼩步,有两种情况:

  • i. 从[i, j] 位置的上⽅( [i - 1, j] 的位置)向下⾛⼀步,转移到[i, j] 位置;
  • ii. 从[i, j] 位置的左⽅( [i, j - 1] 的位置)向右⾛⼀步,转移到[i, j] 位置。

由于我们要求的是有多少种⽅法,因此状态转移⽅程就呼之欲出了: dp[i][j] = dp[i - 1] [j] + dp[i][j - 1] 。

3. 初始化:

可以在最前⾯加上⼀个「辅助结点」,帮助我们初始化。使⽤这种技巧要注意两个点:

  • i. 辅助结点⾥⾯的值要「保证后续填表是正确的」;
  • ii. 「下标的映射关系」

在本题中,「添加⼀⾏」,并且「添加⼀列」后,只需将dp[0][1] 的位置初始化为1 即可。

4. 填表顺序:

根据「状态转移⽅程」的推导来看,

填表的顺序就是「从上往下」填每⼀⾏,在填写每⼀⾏的时候 「从左往右」。

5. 返回值:

根据「状态表⽰」,我们要返回dp[m][n] 的值。

代码:

class Solution
{
public:int uniquePaths(int m, int n){vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // 创建⼀个 dp表 dp[0][1] = 1; // 初始化 // 填表 for (int i = 1; i <= m; i++) // 从上往下 for (int j = 1; j <= n; j++) // 从左往右 dp[i][j] = dp[i - 1][j] + dp[i][j - 1];// 返回结果 return dp[m][n];}
};

测试:

不同路径2.0

解法(动态规划):

算法思路:

本题为不同路径的变型,只不过有些地⽅有「障碍物」,只要在「状态转移」上稍加修改就可解决。

1. 状态表⽰:

对于这种「路径类」的问题,我们的状态表⽰⼀般有两种形式:

  • i. [i, j] 位置出发,巴拉巴拉;
  • ii. 从起始位置出发,到达[i, j] 位置,巴拉巴拉。

这⾥选择第⼆种定义状态表⽰的⽅式: dp[i][j] 表⽰:⾛到[i, j] 位置处,⼀共有多少种⽅式。

2. 状态转移:

简单分析⼀下。如果dp[i][j] 表⽰到达[i, j] 位置的⽅法数,那么到达[i, j] 位置之 前的⼀⼩步,有两种情况:

  • i. 从[i, j] 位置的上⽅( [i - 1, j] 的位置)向下⾛⼀步,转移到[i, j] 位置;
  • ii. 从[i, j] 位置的左⽅( [i, j - 1] 的位置)向右⾛⼀步,转移到[i, j] 位置。
  • 但是, [i - 1, j] 与[i, j - 1] 位置都是可能有障碍的,此时从上⾯或者左边是不可能 到达[i, j] 位置的,也就是说,此时的⽅法数应该是0。 

由此我们可以得出⼀个结论,只要这个位置上「有障碍物」,那么我们就不需要计算这个位置上的 值,直接让它等于0 即可。

3. 初始化:

可以在最前⾯加上⼀个「辅助结点」,帮助我们初始化。使⽤这种技巧要注意两个点:

  • i. 辅助结点⾥⾯的值要「保证后续填表是正确的」;
  • ii. 「下标的映射关系」

在本题中,「添加⼀⾏」,并且「添加⼀列」后,只需将dp[0][1] 的位置初始化为1 即可。

4. 填表顺序:

根据「状态转移⽅程」的推导来看,

填表的顺序就是「从上往下」填每⼀⾏,在填写每⼀⾏的时候 「从左往右」。

5. 返回值:

根据「状态表⽰」,我们要返回dp[m][n] 的值。

代码

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& ob) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回值int m = ob.size(), n = ob[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));dp[1][0] = 1;for (int i = 1; i <= m; i++)for (int j = 1; j <= n; j++)if (ob[i - 1][j - 1] == 0)dp[i][j] = dp[i - 1][j] + dp[i][j - 1];return dp[m][n];}
};

测试:

剑指Offer47.礼物的最⼤价值

方程;

对于dp[i][j] ,我们发现想要到达[i, j] 位置,有两种⽅式:

  • i. 从[i, j] 位置的上⽅[i - 1, j] 位置,向下⾛⼀步,此时到达[i, j] 位置能 拿到的礼物价值为dp[i - 1][j] + grid[i][j] ;
  • ii. 从[i, j] 位置的左边[i, j - 1] 位置,向右⾛⼀步,此时到达[i, j] 位置能 拿到的礼物价值为dp[i][j - 1] + grid[i][j] 

我们要的是最⼤值,因此状态转移⽅程为: dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] 。

代码:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回结果int m = frame.size(), n = frame[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));for (int i = 1; i <= m; i++)for (int j = 1; j <= n; j++)dp[i][j] =max(dp[i - 1][j], dp[i][j - 1]) + frame[i - 1][j - 1];return dp[m][n];}
};

测试:

931.下降路径最小和

 代码:

class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回结果int n = matrix.size();vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX));// 初始化第⼀⾏for (int j = 0; j < n + 2; j++)dp[0][j] = 0;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)dp[i][j] =min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i - 1][j + 1])) +matrix[i - 1][j - 1];//每次只能min两个int ret = INT_MAX;for (int j = 1; j <= n; j++)ret = min(ret, dp[n][j]);return ret;}
};

64.最小路径和

代码:

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size(), n = grid[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));dp[0][1] = dp[1][0] = 0;for (int i = 1; i <= m; i++)for (int j = 1; j <= n; j++)dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];return dp[m][n];}
};

【困难题】 174.地下城游戏(视频讲解)

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

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

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

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

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

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

代码:

class Solution {
public:int calculateMinimumHP(vector<vector<int>>& dungeon) {if (dungeon.empty() || dungeon[0].empty()) {return 0;}int m = dungeon.size(), n = dungeon[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));dp[m][n-1] = dp[m-1][n] = 1; //假设为1,因为后面要取正数的for (int i = m - 1; i >= 0; --i) {for (int j = n - 1; j >= 0; --j) {int minHealth = min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j];dp[i][j] = max(1, minHealth);}}return dp[0][0];}
};

困难题还是有困难的原因的qwq

leetcode 地下城游戏 的一个问题理解

还有一点就是 dp[m][n-1] = dp[m-1][n] = 1

可以理解为他救完公主之后还要有一点血,才能活着

总结:

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

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

相关文章

22-LINUX--多线程and多进程TCP连接

一.TCP连接基础知识 1.套接字 所谓套接字(Socket)&#xff0c;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端&#xff0c;提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲&#xff0c;套接字上联应用进程…

React 中Redux结合React-Redux使用类组件版本(一)

一、Redux是什么&#xff1f; 1.Redux是一个专门用于状态管理的js库 2.它可以用在React、Angular、Vue的项目中&#xff0c;但基本与React配合使用。 3.作用&#xff1a;集中式管理React应用中多个组件共享的状态。 二、Redux 工作流程 三、Redux的三个核心概念 1.action 动…

振弦采集仪在岩土工程监测中的精度与可靠性评估

振弦采集仪在岩土工程监测中的精度与可靠性评估 河北稳控科技振弦采集仪是一种常用的岩土工程土体力学参数监测仪器&#xff0c;它主要用于测量岩土中的应力、应变和模量等力学参数。在岩土工程中&#xff0c;土体力学参数的精确测量对于工程设计、施工和监测都非常重要。因此…

前缀和算法专题

应用: 计算数组中某区间的和 一. 一维前缀和[模版] 答案 二. 二维前缀和[模版] 答案 三. 寻找数组的中心下标 答案 四. 除自身以外数组的乘积 答案 五. 和为k的子数组 答案 六. 和可被k整除的子数组 答案 七. 连续数组 答案 八. 矩阵区域和 答案

如何查看网站的cookie?

前言&#xff1a; 在网络世界中&#xff0c;cookie是一种常见的信息存储方式。 对于开发者和普通用户来说&#xff0c;了解如何查看CSDN的cookie是非常重要的。 本文将介绍几种常用的方法&#xff0c;帮助大家更好地理解和使用cookie&#xff1a; 代码示例&#xff1a; 通过浏…

Docker基础篇之入门使用

文章目录 1. Docker的基本组成2. Docker平台架构3. 阿里云镜像加速4. Docker的Hello World入门案例5. 总结 1. Docker的基本组成 Docker的基本组成主要是有四部分&#xff0c;分别是镜像、容器和仓库。 镜像&#xff1a;Docker镜像就是一个只读的模版&#xff0c;镜像可以用来…

【Spring】深入理解 Spring 状态机:简化复杂业务逻辑的利器

前言 在软件开发中&#xff0c;有许多场景需要处理状态转换和状态驱动的逻辑&#xff0c;比如订单处理、工作流程管理、游戏引擎等。Spring 状态机&#xff08;Spring State Machine&#xff09;是 Spring Framework 提供的一个强大的模块&#xff0c;用于帮助开发人员轻松构建…

二叉搜索树BST ——(C++)

本篇将会讲解有关二叉树的搜索原理&#xff0c;以及关于二叉搜索树的建立&#xff0c;以及二叉树搜索树的插入、删除和查找等基本操作。最后我们还会对二叉搜索树进行功能扩展&#xff0c;介绍有关搜索二叉树的 K 模型和 KV 模型。目录如下&#xff1a; 目录 1. 搜索二叉树 二叉…

前端学习CSS-2

盒子模型 盒子模型相关属性 一些盒子模型的样式示例 传统网页布局方式 浮动 浮动的三大特性 脱标&#xff1a;脱离标准流一行显示&#xff0c;顶部对齐具备行内块元素特性 定位

Java整合EasyExcel实战——1

参考&#xff1a;读Excel | Easy Excel快速使用easyexcel的来完成excel的读取https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read 准备条件 依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifa…

Android 动效整理

Android自定义SeekBar&#xff0c;滑动时弹出气泡指示器显示进度 安卓开发中非常炫的效果集合_android 开发 向右上角收起炫酷动态效果-CSDN博客 https://github.com/shenghuntianlang/Android-Views?tabreadme-ov-file#decentbanner 以前收藏了很多文章&#xff0c;但是过…

【UE5.1 角色练习】08-传送技能

前言 在上一篇&#xff08;【UE5.1 角色练习】07-AOE技能&#xff09;基础上继续实现人物通过鼠标点击然后传送技能的功能。 效果 步骤 1. 首先需要显示鼠标光标&#xff0c;我们可以在玩家控制器中勾选“显示鼠标光标” 2. 在项目设置中添加一个操作映射&#xff0c;设置按…

Python爬虫入门实例:Python7个爬虫小案例(附源码)

引言 随着互联网的快速发展&#xff0c;数据成为了新时代的石油。Python作为一种高效、易学的编程语言&#xff0c;在数据采集领域有着广泛的应用。本文将详细讲解Python爬虫的原理、常用库以及实战案例&#xff0c;帮助读者掌握爬虫技能。 一、爬虫原理 爬虫&#xff0c;又…

2024年上半年信息系统项目管理师下午真题及答案(第二批)

试题一 某项目计划工期为10个月&#xff0c;预算210万元&#xff0c;第7个月结束时&#xff0c;项目经理进行了绩效评估&#xff0c;发现实际完成了总计划进度的70%。项目的实际数据如表所示&#xff1a; 单击下面头像图片领取更多软考独家资料

企业内部通讯软件—WorkPlus适配信创即时通讯软件

在现代企业中&#xff0c;良好的内部通讯是保持高效工作和顺利运营的关键。企业内部通讯软件的选择对于提升沟通效率、促进团队合作、保障数据安全和隐私保护至关重要。本文将介绍企业内部通讯软件的重要性探讨一些常用的软件&#xff0c;帮助企业做出明智的选择。 一、企业内…

深度融合大语言模型与知识图谱:思通数科企业知识库智能问答系统的创新实践

摘要 在知识经济时代&#xff0c;企业知识管理的重要性日益凸显。本文深入探讨了思通数科如何利用大语言模型和知识图谱技术&#xff0c;构建企业知识库智能问答系统&#xff0c;以促进知识的高效获取、共享、应用和创新&#xff0c;从而提升企业的知识管理水平和业务价值。 1…

钕铁硼表面磷化处理

大家都知道烧结钕铁硼易氧化、易腐蚀&#xff0c;日久将造成磁性能的衰减甚至丧失&#xff0c;所以使用前必须进行严格的防腐处理。在之前的文章中已经向大家介绍过与烧结钕铁硼表面处理相关的知识和电镀的工艺流程&#xff0c;除了电镀之外&#xff0c;钕铁硼表面处理还可采用…

Reids高频面试题汇总总结

一、Redis基础 Redis是什么? Redis是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令来操作这些数据结构。Redis的主要特点是什么? 高性能:Redis将数据存储在内…