当前位置: 首页 > article >正文

动态规划之网格图模型(二)

文章目录

  • 动态规划之网格图模型(二)
    • LeetCode 931. 下降路径最小和
      • 思路
      • Golang 代码
    • LeetCode 2684. 矩阵中移动的最大次数
      • 思路
      • Golang 代码
    • LeetCode 2304. 网格中的最小路径代价
      • 思路
      • Golang 代码
    • LeetCode 1289. 下降路径最小和 II
      • 思路
      • Golang 代码
    • LeetCode 3418. 机器人可以获得的最大金币数
      • 思路
      • Golang 代码

动态规划之网格图模型(二)

今天我们继续学习动态规划当中的网格图模型。
在这里插入图片描述

LeetCode 931. 下降路径最小和

思路

题目中已经提到,下降路径可以从这一行当中的任何一个元素开始,也就意味着在一条路径上,某一行的某个元素的上一个元素是它正上方、左上方、右上方某个元素。根据这条性质,我们使用二维数组dp表示(i, j)这个位置的子路径和,据此我们可以写出状态转移方程:dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + matrix[i][j]。注意处理边界情况,也就是元素位于左边界和右边界时,左上方或右上方的元素取不到,因为如果取到的话数组就越界了。

最后取最后一行的最小值,就是最终答案。

Golang 代码

func minFallingPathSum(matrix [][]int) int {m, n := len(matrix), len(matrix[0])dp := make([][]int, m)for i := 0; i < m; i ++ {dp[i] = make([]int, n)}for i := 0; i < n; i ++ {dp[0][i] = matrix[0][i]}for i := 1; i < m; i ++ {for j := 0; j < n; j ++ {if j == 0 {dp[i][j] = min(dp[i - 1][j], dp[i - 1][j + 1]) + matrix[i][j]} else if j == n - 1 {dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + matrix[i][j]} else {dp[i][j] = min(dp[i - 1][j -  1], dp[i - 1][j], dp[i - 1][j + 1]) + matrix[i][j]}}}return slices.Min(dp[m - 1])
}

LeetCode 2684. 矩阵中移动的最大次数

思路

这道题可以使用 DFS 或 BFS 来解决,也可以使用 DP 来解决。 具体来说,最开始我们可以从矩阵第一列的任何位置开始移动,每次只能移动到右、右上、右下三个位置,且移动到的位置需要满足那个位置的元素大于当前位置的元素。通过观察不难发现,能够在矩阵中移动的最大次数等于矩阵的总列数,也就是说,最大次数对应的移动方案就是从第一列移动到最后一列。

如果我们使用 DP,那么可以使用一个二维的数组dp来记录元素(i, j),是否是「可到达的」,因此dp保存的是 bool 值。初始状态下,第一列的所有元素都是可以到达的,所以我们令第一列的 bool 值都为 true。从第二列开始,我们判断每一行的元素是否可到达,判断的依据是当前元素左侧的那一列上是否有满足条件的元素使得从那个元素可以到达当前元素。

由于我们使用 DP 的思路来解题,因此应该反向思考,要到达(i, j),就需要(i, j - 1)(i - 1, j - 1)以及(i + 1, j - 1)当中的一个或多个满足grid[ni][nj] < grid[i][j],这样(i, j)才是可达的。

在遍历某一列的每一行之前,使用一个 bool 值reachable来判断这一列是否可达,如果这一列不可达,那么就没必要继续向右侧的列遍历了,直接返回答案即可。

如果所有列都可达,那么答案就是n - 1,其中n是列数。

Golang 代码

func maxMoves(grid [][]int) int {m, n := len(grid), len(grid[0])dp := make([][]bool, m)for i := 0; i < m; i ++ {dp[i] = make([]bool, n)}// 第一行都是可达的, 对第一行进行初始化for i := 0; i < m; i ++ {dp[i][0] = true}for j := 1; j < n; j ++ {var reachable bool = falsefor i := 0; i < m; i ++ {if dp[i][j - 1] && grid[i][j - 1] < grid[i][j] {dp[i][j] = truereachable = true} else if i >= 1 && dp[i - 1][j - 1] && grid[i - 1][j - 1] < grid[i][j] {dp[i][j] = truereachable = true} else if i <= m - 2 && dp[i + 1][j - 1] && grid[i + 1][j - 1] < grid[i][j] {dp[i][j] = truereachable = true}}if !reachable {return j - 1}}return n - 1
}   

LeetCode 2304. 网格中的最小路径代价

思路

这道题的题目描述非常的复杂,实际上这道题在说的就是从第一行出发,寻找一个到达最后一行的最小代价。最小代价保存在moveCost数组当中,moveCost[i][j]代表的含义就是从值为i的点出发到达下一行第j列的代价。为了更好地理解moveCost,我们以图中值为5的点为例,它在moveCost中的位置就是moveCost[5],由于它位于第一行,因此从它开始到达第二行的40的代价分别是143

讲清楚了问题描述,我们现在就可以开始着手解决问题。仍然使用网格图 DP 的思路来解决当前问题,具体来说,设置一个二维的数组dp,用来记录从「最后一行」开始到达(i, j)位置的最小代价。这里重点强调一下最后一行,因为我们要使用自底向上的思路来解决当前问题,最终的答案是dp[0]这一行的最小值。

dp[i][j]的构成有三部分,第一部分就是从它的下一行某个元素k到达(i, j)的路径代价c,第二部分是从下一行元素已经积累的代价dp[i + 1][k],第三部分是(i, j)本身的值grid[i][j]。汇总三部分可以得到状态转移方程:dp[i][j] = dp[i + 1][k] + c + grid[i][j]。需要再次强调的是,我们使用自底向上的方式来解决问题,所以答案是自底向上更新的。

Golang 代码

func minPathCost(grid [][]int, moveCost [][]int) int {m, n := len(grid), len(grid[0])dp := make([][]int, m)for i := 0; i < m; i ++ {dp[i] = make([]int, n)}// 自底向上, 因此先初始化最后一行的值dp[m - 1] = grid[m - 1]// 最后的答案是 dp 数组第一行的最小值for i := m - 2; i >= 0; i -- {for j := 0; j < n; j ++ {val := grid[i][j]dp[i][j] = math.MaxIntfor k, c := range moveCost[val] {// moveCost 记录的就是从 (i, j) 出发到达下一行第 k 列的那个位置的代价dp[i][j] = min(dp[i][j], dp[i + 1][k] + c)}dp[i][j] += val // 最后需要加上当前位置的值}}return slices.Min(dp[0])
}

LeetCode 1289. 下降路径最小和 II

思路

这道题目与普通版本的「最小路径下降和」比较相似,较大的变化在于当前(i, j)的和可以与上一行的任意列的值累加,且相邻行所选的列不能重复。

我们使用 DP 来解决问题,使用二维数组dp来记录(i, j)位置的最小路径和。由于该位置可以由上一行除j以外任意位置到达,因此我们使用第三重循环来寻找该行最小的路径和,累加得到答案即可。

最终的答案是最后一行的最小值。

Golang 代码

func minFallingPathSum(grid [][]int) int {m, n := len(grid), len(grid[0])dp := make([][]int, m)for i := 0; i < m; i ++ {dp[i] = make([]int, n)}dp[0] = grid[0]for i := 1; i < m; i ++ {dp[i] = grid[i]for j := 0; j < n; j ++ {var val int = math.MaxIntfor k := 0; k < n; k ++ {if j == k {continue}val = min(val, dp[i - 1][k])}dp[i][j] += val}}return slices.Min(dp[m - 1])
}

LeetCode 3418. 机器人可以获得的最大金币数

思路

使用网格图 DP 来解决该问题。每多一个约束条件,DP 数组就应该增加一个维度。对于本题而言,新增加的约束就是「最多可以感化两个单元格」,也就是「最多有两个单元格可以不选」。我们使用三维数组dp来解决问题。第一个和第二个维度对应的是网格图的维度,而第三个维度对应的是「选/不选」的约束。

对于前两个维度而言,(i, j)位置的答案可以由(i - 1, j)(i, j - 1)贡献得到。而对于第三个维度,由于题目已经限定「不选」的最大次数是 2,因此dp[i][j][0]指的就是全选的情况,dp[i][j][1]对应的就是有一次不选的情况,dp[i][j][2]对应的是有两次不选的情况。这一部分的状态更新可以详见代码。

Golang 代码

func maximumAmount(coins [][]int) int {m, n := len(coins), len(coins[0])dp := make([][][3]int, m + 1)for i := 0; i <= m; i ++ {dp[i] = make([][3]int, n + 1)}for i := 0; i <= m; i ++ {dp[i][0] = [3]int{math.MinInt / 2, math.MinInt / 2, math.MinInt / 2}}for i := 0; i <= n; i ++ {dp[0][i] = [3]int{math.MinInt / 2, math.MinInt / 2, math.MinInt / 2}}dp[0][1] = [3]int{}for i := 1; i <= m; i ++ {for j := 1; j <= n; j ++ {x := coins[i - 1][j - 1]dp[i][j][0] = max(dp[i - 1][j][0] + x, dp[i][j - 1][0] + x)dp[i][j][1] = max(dp[i - 1][j][1] + x, dp[i][j - 1][1] + x, dp[i - 1][j][0], dp[i][j - 1][0])dp[i][j][2] = max(dp[i - 1][j][2] + x, dp[i][j - 1][2] + x, dp[i - 1][j][1], dp[i][j - 1][1])}}return dp[m][n][2]
}

相关文章:

动态规划之网格图模型(二)

文章目录 动态规划之网格图模型&#xff08;二&#xff09;LeetCode 931. 下降路径最小和思路Golang 代码 LeetCode 2684. 矩阵中移动的最大次数思路Golang 代码 LeetCode 2304. 网格中的最小路径代价思路Golang 代码 LeetCode 1289. 下降路径最小和 II思路Golang 代码 LeetCod…...

uniapp 集成腾讯云 IM 消息搜索功能

UniApp 集成腾讯云 IM 消息搜索功能实战指南 一、功能实现原理 腾讯云 IM 通过 消息漫游 服务端搜索接口 实现消息检索&#xff0c;核心机制如下&#xff1a; 数据存储&#xff1a;消息默认存储7天&#xff08;可扩展至30天&#xff09;索引构建&#xff1a;基于消息内容自…...

robot_lab——rsl_rl的train.py整体逻辑

文章目录 Go2机器人训练流程详细分析概述1. 训练启动流程1.1 命令行参数解析RSL-RL相关参数组Isaac Sim应用启动参数组 1.2 RL配置1.3 Isaac Sim启动 2. 环境配置加载2.1 Hydra配置系统 3. 环境创建与初始化3.1 Gym环境创建3.2 Manager系统初始化3.2.1 ObservationManager3.2.2…...

AI推荐系统演进史:从协同过滤到图神经网络与强化学习的融合

每一次滑动手机屏幕&#xff0c;电商平台向你推荐心仪商品的背后&#xff0c;是超过百亿量级的浮点运算。从早期的“猜你喜欢”到如今的“比你更懂你”&#xff0c;商品推荐引擎已悄然完成从简单规则到深度智能的技术跃迁。 一、协同过滤&#xff1a;推荐系统的基石与演进 协同…...

Java-IO流之压缩与解压缩流详解

Java-IO流之压缩与解压缩流详解 一、压缩与解压缩概述1.1 基本概念1.2 Java中的压缩类库1.3 核心类与接口 二、ZIP压缩与解压缩2.1 ZIP格式简介2.2 使用ZipOutputStream创建ZIP文件2.3 使用ZipInputStream读取ZIP文件 三、GZIP压缩与解压缩3.1 GZIP格式简介3.2 使用GZIPOutputS…...

.NET 原生驾驭 AI 新基建实战系列(三):Chroma ── 轻松构建智能应用的向量数据库

在人工智能AI和机器学习ML迅猛发展的今天&#xff0c;数据的存储和检索需求发生了巨大变化。传统的数据库擅长处理结构化数据&#xff0c;但在面对高维向量数据时往往力不从心。向量数据库作为一种新兴技术&#xff0c;专为AI应用设计&#xff0c;能够高效地存储和查询高维向量…...

有声书画本

有声书画本服务标准 有声喵连接 一、基础服务&#xff08;5r/w字&#xff09; 核心&#xff1a; 基础删&#xff08;快捷键AltD&#xff09;调&#xff0c;优化播讲流畅度 执行&#xff1a; 删除冗余旁白 删除角色动作/心理的重复描述&#xff08;例&#xff1a;小明冷笑道…...

StarRocks与Apache Iceberg:构建高效湖仓一体的实时分析平台

## 引言&#xff1a;数据湖的挑战与演进 在数据驱动的时代&#xff0c;企业数据湖需要同时满足海量存储、高性能查询、多引擎协作和实时更新等复杂需求。传统基于 Hive 的数据湖方案面临元数据管理低效、缺乏 ACID 事务支持、查询性能瓶颈等问题。在此背景下&#xff0c;**Sta…...

WebRTC 与 WebSocket 的关联关系

WebRTC&#xff08;Web Real-Time Communication&#xff09;与 WebSocket 作为重要技术&#xff0c;被广泛应用于各类实时交互场景。虽然它们在功能和特性上存在明显差异&#xff0c;但在实际应用中也有着紧密的关联&#xff0c;共同为用户提供流畅的实时交互体验。 一、WebR…...

8.RV1126-OPENCV 视频中添加LOGO

一.视频中添加 LOGO 图像大体流程 首先初始化VI,VENC模块并使能&#xff0c;然后创建两个线程&#xff1a;1.把LOGO灰度化&#xff0c;然后获取VI原始数据&#xff0c;其次把VI数据Mat化并创建一个感兴趣区域&#xff0c;最后把LOGO放感兴趣区域里并把数据发送给VENC。2.专门获…...

API管理是什么?API自动化测试怎么搭建?

目录 一、API管理是什么 &#xff08;一&#xff09;API管理的定义 &#xff08;二&#xff09;API管理的重要性 二、API管理的主要内容 &#xff08;一&#xff09;API设计 1. 遵循标准规范 2. 考虑可扩展性 3. 保证接口的易用性 &#xff08;二&#xff09;API开发 …...

Next.js+prisma开发一

1.初始化Next.js项目 #按版本安装 npx create-next-app13.4.5 如果最新版本 执行&#xff1a;npx create-next-applatest2. 安装Prima和客户端 npm install prisma --save-dev npm install prisma/client3.初始化Prisma&#xff0c;以SQLit举例 # 初始化 Prisma 并配置 SQLi…...

GIC v3 v4 虚拟化架构

ARMV8-A架构中包含了对虚拟化的支持。为了与架构保持匹配&#xff0c;GICV3也对虚拟化做了支持。新增了以下特性&#xff1a; 对CPU interface的硬件虚拟化虚拟中断maintenance 中断&#xff1a;用于通知监管程序&#xff08;例如hypervisor&#xff09;一些特定的虚拟机事件 …...

2025远离Deno和Fresh

原创作者&#xff1a;庄晓立&#xff08;LIIGO&#xff09; 原创时间&#xff1a;2025年6月6日 原创链接&#xff1a;https://blog.csdn.net/liigo/article/details/148479884 版权所有&#xff0c;转载请注明出处&#xff01; 相识 Deno&#xff0c;是Nodejs原开发者Ryan Da…...

相机camera开发之差异对比核查一:测试机和对比机的硬件配置差异对比

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、背景 二、:Camera硬件配置差异 2.1:硬件配置差异核查项 2.2 :核查方式 2.3 :高通camx平台核查 2.4 :MTK平台核查...

Flask+LayUI开发手记(七):头像的上传及突破static目录限制

看了看&#xff0c;上篇开发手记是去年8月份写的&#xff0c;到现在差2个月整一年了。停更这么长时间&#xff0c;第一个原因是中间帮朋友忙一个活&#xff0c;那个技术架构是用springboot的&#xff0c;虽然前端也用layUI&#xff0c;但和Flask-python完全不搭界&#xff0c;所…...

uv管理spaCy语言模型

本文记录如何在使用uv管理python项目dependencies时&#xff0c;把spaCy的模型也纳入其中. spaCy 一、spaCy简介 spaCy是一个开源的自然语言处理&#xff08;NLP&#xff09;库&#xff0c;它主要用于处理文本数据。它支持多种语言&#xff0c;包括英语、中文等。它是由Expl…...

MiniExcel模板填充Excel导出

目录 1.官方文档 2. 把要导出的数据new一个匿名对象 3.导出 4.注意事项 5.模板制作 6.结果 1.官方文档 https://gitee.com/dotnetchina/MiniExcel/#%E6%A8%A1%E6%9D%BF%E5%A1%AB%E5%85%85-excel // 1. By POCO var value new {Name "Jack",CreateDate n…...

NoSQL之redis哨兵

一、哨兵的核心功能 监控&#xff08;Monitoring&#xff09; 持续检查主节点和从节点的运行状态&#xff08;是否存活、延迟等&#xff09;。 自动故障转移&#xff08;Automatic Failover&#xff09; 当主节点不可用时&#xff0c;自动选举一个从节点升级为主节点。 更新…...

MCP协议重构AI Agent生态:万能插槽如何终结工具孤岛?

前言 在人工智能技术快速发展的2025年&#xff0c;MCP(Model Context Protocol&#xff0c;模型上下文协议)正逐渐成为AI Agent生态系统的关键基础设施。这一由Anthropic主导的开放协议&#xff0c;旨在解决AI模型与外部工具和数据源之间的连接难题&#xff0c;被业界形象地称…...

阿里云事件总线 EventBridge 正式商业化,构建智能化时代的企业级云上事件枢纽

作者&#xff1a;肯梦、稚柳 产品演进历程&#xff1a;在技术浪潮中的成长之路 早在 2018 年&#xff0c;Gartner 评估报告便将事件驱动模型&#xff08;Event-Driven Model&#xff09;列为十大战略技术趋势之一&#xff0c;指出事件驱动架构&#xff08;EDA&#xff0c;Eve…...

CentOS8.3+Kubernetes1.32.5+Docker28.2.2高可用集群二进制部署

一、准备工作 1.1 主机列表 HostnameHost IPDocker IPRolek8s31.vm.com192.168.26.3110.26.31.1/24master&worker、etcd、dockerk8s32.vm.com192.168.26.3210.26.32.1/24master&worker、etcd、dockerk8s33.vm.com192.168.26.3310.26.33.1/24master&worker、etcd、…...

学习日记-day23-6.6

完成目标&#xff1a; 知识点&#xff1a; 1.IO流_转换流使用 ## 转换流_InputStreamReader1.字节流读取中文在编码一致的情况,也不要边读边看,因为如果字节读不准,读不全,输出的内容有可能会出现乱码 2.所以,我们学了字符流,字符流读取文本文档中的内容如果编码一致,就不会出…...

Pytorch安装后 如何快速查看经典的网络模型.py文件(例如Alexnet,VGG)(已解决)

当你用conda 安装好虚拟环境后&#xff0c; 找到你的Anaconda 的安装位置。 我的在D盘下&#xff1b; 然后 从Anaconda3文件夹开始&#xff1a;一级一级的查看&#xff0c;一直到models Anaconda3\envs\openmmlab\Lib\site-packages\torchvision\models 在models下面&#x…...

《ERP原理与应用教程》第3版习题和答案

ERP原理与应用教程是一门系统介绍企业资源计划(Enterprise Resource Planning, ERP)系统核心理论、技术架构及实施应用的综合性课程。它主要面向管理类、信息类、工程类等专业学生及企业管理者,旨在培养对现代企业信息化管理的理解与实践能力。以下是该课程的详细解析: 一…...

JavaScript中的正则表达式:文本处理的瑞士军刀

JavaScript中的正则表达式&#xff1a;文本处理的瑞士军刀 在编程世界中&#xff0c;正则表达式&#xff08;Regular Expression&#xff0c;简称RegExp&#xff09;被誉为“文本处理的瑞士军刀”。它能够高效地完成字符串匹配、替换、提取和验证等任务。无论是前端开发中的表…...

vue对axios的封装和使用

在 Vue 项目中&#xff0c;使用 axios 进行 HTTP 请求是非常常见的做法。为了提高代码的可维护性、统一错误处理和请求拦截/响应拦截逻辑&#xff0c;对axios进行封装使用。 一、基础封装&#xff08;适用于 Vue 2 / Vue 3&#xff09; 1. 安装 axios npm install axios2. 创…...

软考 系统架构设计师系列知识点之杂项集萃(82)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;81&#xff09; 第148题 “41”视图主要用于描述系统逻辑架构&#xff0c;最早由Philippe Kruchten于1995年提出。其中&#xff08; &#xff09;视图用于描述对象模型&#xff0c;并说明系统应该…...

DrissionPage调试工具:网页自动化与数据采集的革新利器

在网页自动化测试与数据采集领域&#xff0c;开发者长期面临两难选择&#xff1a;使用Selenium等工具操作浏览器时效率不足&#xff0c;而直接调用Requests库又难以应对复杂动态页面。DrissionPage的出现完美解决了这一矛盾&#xff0c;这款基于Python开发的工具创新性地将浏览…...

有人-无人(人机)交互记忆、共享心智模型与AI准确率的边际提升

有人-无人&#xff08;人机&#xff09;交互记忆、共享心智模型与AI准确率的边际提升是人工智能发展中相互关联且各有侧重的三个方面。人机交互记忆通过记录和理解用户与机器之间的交互历史&#xff0c;增强机器对用户需求的个性化响应能力&#xff0c;从而提升用户体验和协作效…...