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

news2025/6/7 14:58:49

文章目录

  • 动态规划之网格图模型(二)
    • 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 = false
        for i := 0; i < m; i ++ {
            if dp[i][j - 1] && grid[i][j - 1] < grid[i][j] {
                dp[i][j] = true
                reachable = true
            } else if i >= 1 && dp[i - 1][j - 1] && grid[i - 1][j - 1] < grid[i][j] {
                dp[i][j] = true
                reachable = true
            } else if i <= m - 2 && dp[i + 1][j - 1] && grid[i + 1][j - 1] < grid[i][j] {
                dp[i][j] = true
                reachable = 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.MaxInt
            for 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.MaxInt
            for 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]
}

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

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

相关文章

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…

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

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

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开发 …

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…

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

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

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…

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…

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

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

【OpenGL学习】(五)自定义着色器类

文章目录 【OpenGL学习】&#xff08;五&#xff09;自定义着色器类着色器类插值着色统一着色 【OpenGL学习】&#xff08;五&#xff09;自定义着色器类 项目结构&#xff1a; 着色器类 // shader_s.h #ifndef SHADER_H #define SHADER_H#include <glad/glad.h>#inc…

408第一季 - 数据结构 - 栈与队列的应用

括号匹配 用瞪眼法就可以知道的东西 栈在表达式求值运用 先简单看看就行&#xff0c;题目做了就理解了 AB是操作符,也是被狠狠加入后缀表达式了&#xff0c;然后后面就是*&#xff0c;只要优先级比栈顶运算符牛逼就放里面&#xff0c;很显然&#xff0c;*比牛逼 继续前进&#…

超声波清洗设备的清洗效果如何?

超声波清洗设备是一种常用于清洗各种物体的技术&#xff0c;它通过超声波振荡产生的微小气泡在液体中破裂的过程来产生高能量的冲击波&#xff0c;这些冲击波可以有效地去除表面和细微裂缝中的污垢、油脂、污染物和杂质。超声波清洗设备在多个领域得到广泛应用&#xff0c;包括…

“草台班子”的成长路径分析

一、草台班子的起点&#xff1a;用最小成本验证价值 特点&#xff1a; 团队规模小&#xff08;通常3-5人&#xff09;&#xff0c;成员背景杂&#xff08;可能是程序员产品经理运营的混搭&#xff09;&#xff1b;资源匮乏&#xff08;无资金、无技术中台、无客户积累&#x…

软件测评服务如何依据标准确保品质?涵盖哪些常见内容?

软件测评服务涉及对软件的功能和性能等多维度进行评估和检验&#xff0c;这一过程有助于确保软件的品质&#xff0c;降低故障发生率及维护费用&#xff0c;对于软件开发和维护环节具有至关重要的价值。 测评标准依据 GB/T 25000.51 - 2016是软件测评的核心依据。依照这一标准…

Python打卡第46天

浙大疏锦行 注意力 注意力机制是一种让模型学会「选择性关注重要信息」的特征提取器&#xff0c;就像人类视觉会自动忽略背景&#xff0c;聚焦于图片中的主体&#xff08;如猫、汽车&#xff09;。 从数学角度看&#xff0c;注意力机制是对输入特征进行加权求和&#xff0c;…