【动态规划】dp 路径问题(不同路径、路径最小和、地下城游戏...)

news2025/2/24 6:55:06

文章目录

  • 1. 前言 - 理解动态规划算法
  • 1.5 关于dp路径问题
  • 2. 例题
    • 2.1_不同路径
      • Warning. 关于状态表示
  • 3. 算法题
    • 3.1_不同路径II
    • 3.2_珠宝的最高价值
    • 3.3_下降路径最小和
    • 3.4_最小路径和
    • 3.5_地下城游戏
      • 关于状态表示的两种选法:

1. 前言 - 理解动态规划算法

关于 动态规划的理解 与例题,点击👇

【动态规划】C++解决斐波那契模型题目(三步问题、爬楼梯、解码方法…)

有了上面的经验,我们来解下面 dp的路径问题

1.5 关于dp路径问题

  • 在路径问题中,通常需要找到从起点到终点的一条路径,使得路径满足一定的约束条件(如最短路径、最大价值路径等)。

  • 在动态规划中,通常采用一个二维数组或类似的数据结构来存储中间状态,其中每个状态表示从起点到当前位置的某种信息(如路径长度、路径价值等)。

在这里插入图片描述


2. 例题

2.1_不同路径

在这里插入图片描述

思路

  1. 首先 找状态表示 状态转移方程

在这里插入图片描述

Warning. 关于状态表示

实际上在分析状态表示 时,一般会考虑两种表示法

  1. 以(i, j)位置为终点 时的count
  2. 以(i, j)位置为起点 到终点时的count

在本章算法题中,仅最后一道题会涉及到两种表示法,其余的题以第一种即可解题。


  1. 随后进行 对表中内容的初始化 (以及细节问题:填表顺序、返回值)

在这里插入图片描述

代码

class Solution {
public:
    int uniquePaths(int m, int n) {
        // 创建dp表
        vector<vector<int>> dp(m + 1, vector<int>(n + 1)); // 虚拟空间

        // 填写虚拟空间(默认为0!!)
        // for(int i = 0; i <= m; ++i) dp[0][i] = 0;
        // for(int j = 0; j <= n; ++j) dp[j][0] = 0;
        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];
    }
};

3. 算法题


3.1_不同路径II

在这里插入图片描述

思路

读题后,我们发现本题比起之前的,仅仅加了障碍物的限制。

  • 所以我们只需要在填表时加一句判断即可,当(i, j)位置不为障碍物时,进行填表dp[i][j]。
    • 为什么?
      • 当(i, j)为障碍物,dp[i][j]为0,不做统计。

代码

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int m = obstacleGrid.size(), n = obstacleGrid[0].size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1)); // 初始化dp数组(虚拟空间+1行1列)
        dp[0][1] = 1;
        
        for(int i = 1; i <= m; ++i)
            for(int j = 1; j <= n; ++j)
            {
                if(obstacleGrid[i - 1][j - 1] == 0) // 虚拟空间多加了一行一列,找初始矩阵时,映射下标要-1
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }

        return dp[m][n];
    }
};

3.2_珠宝的最高价值

在这里插入图片描述

思路

  1. 首先 找状态表示 状态转移方程

在这里插入图片描述

  1. 随后进行 对表中内容的初始化 (以及细节问题:填表顺序、返回值)

在这里插入图片描述

代码

class Solution {
public:
    int jewelleryValue(vector<vector<int>>& frame) {
        int m = frame.size(), n = frame[0].size();
        // dp的创建 与 元素初始化
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));

        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]; // 映射下标(对于frame要-1)

        return dp[m][n];
    }
};

3.3_下降路径最小和

在这里插入图片描述

思路

不再过多解释,直接跟着思路五步走:

在这里插入图片描述

在这里插入图片描述

代码

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        int n = matrix.size();
        vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX)); // 先初始化为 大值
        for(int j = 0; j <= n + 1; ++j) dp[0][j] = 0; // 将第一行初始化为0
        
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
            {
                // 映射下标,matrix下标-1
                dp[i][j] = min(min(dp[i-1][j], dp[i-1][j-1]), dp[i-1][j+1]) + matrix[i-1][j-1]; 
            }

        // 找最后一行的最小值
        int ret = INT_MAX;
        for(int j = 1; j <= n; ++j) ret = min(ret, dp[n][j]);
        return ret;
    }
};

3.4_最小路径和

在这里插入图片描述

思路

  • 题目分析:本题不再画图,根据题目可以看出来和《珠宝的最高价值》一题是极为相似的,需要注意的是初始化时虚拟空间值的设置。

代码

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)); // 虚拟空间+1行1列。初始化为无穷大
        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]; // grid 映射下标(需要-1)

        return dp[m][n];
    }
};


3.5_地下城游戏

在这里插入图片描述

思路

关于状态表示的两种选法:

下面介绍了,为什么对于本题我们无法继续以(i, j)位置为终点,找健康点数
在这里插入图片描述
设置了正确的状态表示才能写出正确的状态转移方程:

在这里插入图片描述
最后进行内容初始化以及其余细节问题:

在这里插入图片描述

代码

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int m = dungeon.size(), n = dungeon[0].size();
       // dp[i][j]: 以(i, j)位置开始,到达终点的 最低初始健康点数
        // 右侧下侧扩充一行一列
        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+1][j], dp[i][j+1]) - dungeon[i][j];
                dp[i][j] = max(1, dp[i][j]); // 防止负数血量的出现
            }

        return dp[0][0];
    }
};

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

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

相关文章

使用甘特图来做时间管理

在这个追求效率的时代,掌握高超的时间管理技能几乎等同于掌控了成功。事实上,时间就是金钱,更是稀缺资源。那么,如何高效地规划和利用时间呢?甘特图应该是您的必备武器之一。 甘特图(Gantt chart)名字虽然有些陌生,但它的使用范围确实广泛。无论是全职妈妈安排家务,还是上市公…

数据结构习题-- 相交链表

数据结构习题-- 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 如上图&#xff0c;返回c1结点 注意&#xff1a;这两个链表非环形 方法&#xff1a;集合 分析 由…

大型网站系统架构演化实例_7.使用NoSQL和搜索引擎

1.使用NoSQL和搜索引擎 随着网站业务越来越复杂&#xff0c;对数据存储和检索的需求也越来越复杂&#xff0c;网站需要采用一些非关系数据库技术如NoSQL和非数据库查询技术如搜索引擎。NoSQL和搜索引擎都是源自互联网的技术手段&#xff0c;对可伸缩的分布式特性具有更好的支持…

MyBatis使用PageHelper分页插件

1、不使用PageHelper分页插件 模块名&#xff1a;mybatis-012-page CarMapper接口package org.example.mapper;import org.apache.ibatis.annotations.Param; import org.example.pojo.Car;import java.util.List;public interface CarMapper {/*** 分页查询* param startInd…

vue 下载文件 处理后台返回的文件流

1. 下载文件很常见&#xff0c;下载成各种格式的也很常见&#xff0c;本质就是后台返回一个文件流&#xff0c;我们前端去处理一下就行&#xff0c;但是如果因为某些条件&#xff0c;没有返回文件流&#xff0c;返回告诉你&#xff0c;文件出现错误了&#xff0c;那我们就需要把…

使用示例解释.NET中的Mocking是什么?

让我们踏上探索.NET软件开发中Mocking概念的旅程&#xff0c;让我们深入了解Mocking是多么简单易懂、易于访问。请与我一起穿越这个主题&#xff0c;我将涵盖以下内容&#xff1a; 理解Mocking&#xff1a;为何它对于构建强大的测试策略至关重要。探索一些最常见的Mocking库&a…

学习Rust的第11天:模块系统

Today we are taking a look at the module system of rust. We can use this to manage growing projects and keep track of what modules is stored where… 今天我们来看看Rust的模块系统。我们可以使用它来管理不断增长的项目&#xff0c;并跟踪 modules 存储在何处。 Rus…

mysql四种引擎区别

MySQL 提供了多种不同的数据库引擎&#xff0c;其中最常见的有 MyISAM、InnoDB、MEMORY 和 BLACKHOLE。这四个引擎分别有以下特点&#xff1a; 1. MyISAM MyISAM 是 MySQL 的默认引擎。它对于只有较少的修改、大量读取的应用场景具有良好的性能。它不支持事务处理&#xff0c;也…

如何查看微信公众号发布文章的主图,如何看微信文章的主图,怎么才能拿到主图

如何查看&#xff0c;微信公众号发布文章的主图&#xff0c;如何看微信文章的主图 起因是这样的&#xff0c;当我看到一篇文章的时候&#xff0c;他的主图很漂亮&#xff0c;但是&#xff0c;正文里没有&#xff0c;而我又想看到&#xff0c;并且使用这张图片&#xff0c;该怎么…

社交媒体数据恢复:BF Messager

BF Messenger 数据恢复方法 一、前言 BF Messenger&#xff08;BF加密聊天软件&#xff09;是一款基于布尔式循环移位加密算法的聊天应用程序。它使用对称密钥加密技术&#xff0c;用户可以在安全的环境下进行私密聊天。除此之外&#xff0c;该应用还具有防截屏、应用锁屏、密…

使用 Docker 部署 SurveyKing 调查问卷系统

1&#xff09;SurveyKing 介绍 SurveyKing 是一款功能强大、操作简便的开源问卷系统。它不仅满足了用户对问卷调查的基本需求&#xff0c;还提供了丰富的逻辑设置和灵活的问题设置&#xff0c;使得问卷制作更加智能化和个性化。此外&#xff0c;SurveyKing 还具有快速部署和安全…

gin框架提高篇(四)

参数校验&#xff08;一&#xff09; uuid包&#xff1a;https://github.com/satori/go.uuid 因为作者更改了参数限制&#xff0c;导致会出问题 → 问题解决 package mainimport ("fmt""github.com/gin-gonic/gin""github.com/go-playground/validato…

STL容器搜索:当直接访问STL容器时,如何执行有效和正确的搜索?

在访问STL容器时进行搜索 一、简介二、std::vector, std::deque, std::list三、std::map, std::multimap, std::set, std::multiset四、std::string六、总结 一、简介 本文主要了解如何在直接访问c容器时高效地进行搜索。在STL容器中搜索&#xff0c;要牢记一个原则&#xff1…

禾赛面经分享

前言 禾赛的linux开发工程师&#xff08;实习&#xff09;&#xff0c;base是上海&#xff0c;以下是面试遇到的一些问题。 目录 前言题目与答案C语言部分嵌入式相关手撕题 题目与答案 C语言部分 static关键字的作用 static修饰局部变量时&#xff1a;①改变了其存储位置&…

基础知识集合

https://blog.csdn.net/sheng_q/category_10901984.html?spm1001.2014.3001.5482 epoll 事件驱动的I/O模型&#xff0c;同时处理大量的文件描述符 内核与用户空间共享一个事件表&#xff1a;监控的文件描述符以它们的状态&#xff0c;当状态变化&#xff0c;内核将事件通知给…

【分治】Leetcode 库存管理 III

题目讲解 LCR 159. 库存管理 III 本题的含义就是让求出最小的k个数 算法讲解 class Solution { public:void my_qsort(vector<int>& nums, int l, int r){if(l > r) return ;int i l, left l-1, right r1;int key nums[rand() % (r - l 1) l];//完成分三…

大数据真题讲解系列——拼多多数据分析面试题

拼多多数据分析面试题&#xff1a;连续3次为球队得分的球员名单 问题&#xff1a; 两支篮球队进行了激烈的比赛&#xff0c;比分交替上升。比赛结束后&#xff0c;你有一个两队分数的明细表&#xff08;名称为“分数表”&#xff09;。表中记录了球队、球员号码、球员姓名、得…

hv第一坑:定时器

错误代码 重试策略&#xff1a;一次延迟1s,最长30s直至事件成功。 int try_count 0;//do something if(not success)m_loop->setTimerInLoop((try_count > 30 ? 30: try_count) *1000 , cb, INFINITE, 0x100);表现现象 cpu 爆了内存爆了 总结原因 hv内部代码bug&…

Maven通过flatten-maven-plugin插件实现多模块版本统一管理

正文 起因是公司开始推代码版本管理的相关制度&#xff0c;而开发过程中经常使用多模块构建项目&#xff0c;每次做版本管理时都需要对每个模块及子模块下的pom文件中parent.version和模块下依赖中的version进行修改&#xff0c;改的地方非常多&#xff0c;且非常容易漏。为此…

如何用Python构建一个生产级别的电影推荐系统 - 机器学习手册

构建项目是彻底学习概念并发展必要技能的最有效方式之一。 项目使您沉浸在现实世界的问题解决中&#xff0c;巩固您的知识&#xff0c;并培养批判性思维、适应能力和项目管理专业知识。 本指南将带您逐步构建一个根据用户喜好量身定制的电影推荐系统。我们将利用一个庞大的包…