【C++动态规划 网格】2328. 网格图中递增路径的数目|2001
本文涉及知识点
C++动态规划
LeetCode2328. 网格图中递增路径的数目
给你一个 m x n 的整数网格图 grid ,你可以从一个格子移动到 4 个方向相邻的任意一个格子。
请你返回在网格图中从 任意 格子出发,达到 任意 格子,且路径中的数字是 严格递增 的路径数目。由于答案可能会很大,请将结果对 109 + 7 取余 后返回。
如果两条路径中访问过的格子不是完全相同的,那么它们视为两条不同的路径。
示例 1:
输入:grid = [[1,1],[3,4]]
输出:8
解释:严格递增路径包括:
- 长度为 1 的路径:[1],[1],[3],[4] 。
- 长度为 2 的路径:[1 -> 3],[1 -> 4],[3 -> 4] 。
- 长度为 3 的路径:[1 -> 3 -> 4] 。
路径数目为 4 + 3 + 1 = 8 。
示例 2:
输入:grid = [[1],[2]]
输出:3
解释:严格递增路径包括: - 长度为 1 的路径:[1],[2] 。
- 长度为 2 的路径:[1 -> 2] 。
路径数目为 2 + 1 = 3 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 1000
1 <= m * n <= 105
1 <= grid[i][j] <= 105
动态规划 网格
动态规划的状态表示
dp[r][c] 表示以单格(r,c)为终点的路径数量。空间复杂度:O(mn)。
动态规划的填报顺序
单格值从小到大枚举后序状态。
动态规划的转移方程
(r,c)的任意临接点(r1,c1)且grid[r1][c1] < gird[r][c]
dp[r][c] += (dp[r1][c1]) ,如果不存在临接点。dp[r][c]为1。
动态规划的初始值
dp全为1。
动态规划的返回值
∑ \sum ∑(dp)
代码
核心代码
template<int MOD = 1000000007>
class C1097Int
{
public:C1097Int(long long llData = 0) :m_iData(llData% MOD){}C1097Int operator+(const C1097Int& o)const{return C1097Int(((long long)m_iData + o.m_iData) % MOD);}C1097Int& operator+=(const C1097Int& o){m_iData = ((long long)m_iData + o.m_iData) % MOD;return *this;}C1097Int& operator-=(const C1097Int& o){m_iData = (m_iData + MOD - o.m_iData) % MOD;return *this;}C1097Int operator-(const C1097Int& o){return C1097Int((m_iData + MOD - o.m_iData) % MOD);}C1097Int operator*(const C1097Int& o)const{return((long long)m_iData * o.m_iData) % MOD;}C1097Int& operator*=(const C1097Int& o){m_iData = ((long long)m_iData * o.m_iData) % MOD;return *this;}C1097Int operator/(const C1097Int& o)const{return *this * o.PowNegative1();}C1097Int& operator/=(const C1097Int& o){*this /= o.PowNegative1();return *this;}bool operator==(const C1097Int& o)const{return m_iData == o.m_iData;}bool operator<(const C1097Int& o)const{return m_iData < o.m_iData;}C1097Int pow(long long n)const{C1097Int iRet = 1, iCur = *this;while (n){if (n & 1){iRet *= iCur;}iCur *= iCur;n >>= 1;}return iRet;}C1097Int PowNegative1()const{return pow(MOD - 2);}int ToInt()const{return m_iData;}
private:int m_iData = 0;;
};class CGrid {
public:CGrid(int rCount, int cCount) :m_r(rCount), m_c(cCount) {}template<class Fun1,class Fun2>vector<vector<pair<int, int>>> NeiBo(Fun1 funVilidCur, Fun2 funVilidNext, int iConnect = 4){vector<vector<pair<int, int>>> vNeiBo(m_r * m_c);for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (!funVilidCur(r, c))continue;auto& v = vNeiBo[Mask(r, c)];if ((r > 0)&& funVilidNext(r-1, c)) {v.emplace_back(r-1, c);}if ((c > 0) && funVilidNext(r , c - 1)) {v.emplace_back(r, c - 1);}if ((r+1 < m_r ) && funVilidNext(r + 1, c)) {v.emplace_back(r + 1, c);}if ((c+1 <m_c ) && funVilidNext(r, c + 1)) {v.emplace_back(r, c + 1);}}}return vNeiBo;}vector<vector<int>> Dis( vector<pair<int, int>> start, std::function<bool(int, int)> funVilidCur, std::function<bool(int, int)> funVilidNext, const int& iConnect = 4) {static short dir[8][2] = { {0, 1}, {1, 0}, {-1, 0},{ 0, -1},{1,1},{1,-1},{-1,1},{-1,-1} };vector<vector<int>> vDis(m_r, vector<int>(m_c, -1));for (const auto& [r, c] : start) {vDis[r][c] = 0;}for (int i = 0; i < start.size(); i++) {const auto [r, c] = start[i];if (!funVilidCur(r, c)) { continue; }for (int k = 0; k < iConnect; k++) {const int r1 = r + dir[k][0];const int c1 = c + dir[k][1];if ((r1 < 0) || (r1 >= m_r) || (c1 < 0) || (c1 >= m_c)) { continue; }if (funVilidNext(r1, c1) && (-1 == vDis[r1][c1])) {start.emplace_back(r1, c1);vDis[r1][c1] = vDis[r][c] + 1;}}}return vDis;}void EnumGrid(std::function<void(int, int)> call){for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){call(r, c);}}} vector<pair<int, int>> GetPos(std::function<bool(int, int)> fun) {vector<pair<int, int>> ret;for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (fun(r, c)) {ret.emplace_back(r, c);}}}return ret;}inline int Mask(int r, int c) { return m_c * r + c; }const int m_r, m_c;const inline static int s_Moves[][2] = { {1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1} };
};class Solution {public:int countPaths(vector<vector<int>>& grid) {const int R = grid.size();const int C = grid[0].size();CGrid gr(R, C);auto fun = [&](int r, int c) {return true; };auto neiBo = gr.NeiBo(fun, fun);vector<tuple<int, int, int>> v;auto Cal = [&](int r, int c) {v.emplace_back(grid[r][c], r, c);};gr.EnumGrid(Cal);sort(v.begin(), v.end());vector<vector<C1097Int<>>> dp(R, vector<C1097Int<>>(C, C1097Int<>(1)));C1097Int<> ans;for (auto [tmp, r, c] : v) {for (auto [r1, c1] : neiBo[gr.Mask(r, c)]) {if (grid[r1][c1] >= tmp)continue;dp[r][c] += dp[r1][c1];}ans += dp[r][c];}return ans.ToInt();}};
单元测试
vector<vector<int>> grid;TEST_METHOD(TestMethod11){grid = { {1,1},{3,4} };auto res = Solution().countPaths(grid);AssertEx(8, res);}TEST_METHOD(TestMethod12){grid = { {1},{2} };auto res = Solution().countPaths(grid);AssertEx(3, res);}

扩展阅读
| 我想对大家说的话 |
|---|
| 工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
| 学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
| 有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
| 闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
| 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
| 如果程序是一条龙,那算法就是他的是睛 |
| 失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

相关文章:
【C++动态规划 网格】2328. 网格图中递增路径的数目|2001
本文涉及知识点 C动态规划 LeetCode2328. 网格图中递增路径的数目 给你一个 m x n 的整数网格图 grid ,你可以从一个格子移动到 4 个方向相邻的任意一个格子。 请你返回在网格图中从 任意 格子出发,达到 任意 格子,且路径中的数字是 严格递…...
Web3.0时代的挑战与机遇:以开源2+1链动模式AI智能名片S2B2C商城小程序为例的深度探讨
摘要:Web3.0作为互联网的下一代形态,承载着去中心化、开放性和安全性的重要愿景。然而,其高门槛、用户体验差等问题阻碍了Web3.0的主流化进程。本文旨在深入探讨Web3.0面临的挑战,并提出利用开源21链动模式、AI智能名片及S2B2C商城…...
MySQL(高级特性篇) 12 章——数据库其它调优策略
一、数据库调优的措施 (1)调优的目标 尽可能节省系统资源,以便系统可以提供更大负荷的服务(吞吐量最大)合理的结构设计和参数调整,以提高用户操作的响应速度(响应速度更快)减少系统…...
单片机基础模块学习——DS18B20温度传感器芯片
不知道该往哪走的时候,就往前走。 一、DS18B20芯片原理图 该芯片共有三个引脚,分别为 GND——接地引脚DQ——数据通信引脚VDD——正电源 数据通信用到的是1-Wier协议 优点:占用端口少,电路设计方便 同时该协议要求通过上拉电阻…...
掌握长尾关键词优化技巧提升SEO效果与流量增长策略
内容概要 长尾关键词是指由三个或更多个词组成的关键词,这类关键词通常搜索量相对较低,但在搜索引擎优化(SEO)中的作用却不可忽视。它们能够精确定位用户的需求,因为长尾关键词往往反映了用户更具体的搜索意图。掌握长…...
AAAI2024论文解读|HGPROMPT Bridging Homogeneous and Heterogeneous Graphs
论文标题 HGPROMPT: Bridging Homogeneous and Heterogeneous Graphs for Few-shot Prompt Learning 跨同构异构图的小样本提示学习 论文链接 HGPROMPT: Bridging Homogeneous and Heterogeneous Graphs for Few-shot Prompt Learning论文下载 论文作者 Xingtong Yu, Yuan…...
高频 SQL 50 题(基础版)_620. 有趣的电影
高频 SQL 50 题(基础版)_620. 有趣的电影 一级目录 表:cinema id 是该表的主键(具有唯一值的列)。 每行包含有关电影名称、类型和评级的信息。 评级为 [0,10] 范围内的小数点后 2 位浮点数。 编写解决方案,找出所有影片描述为 …...
git的理解与使用
本地的git git除了最经典的add commit push用来做版本管理,其实他的分支管理也非常强大 可以说你学好了分支管理,就可以完成团队的配合协作了 git仓库 我们可以使用git init来初始化一个git仓库,只要能看见.git文件夹,就代表这…...
Java进阶(一)
目录 一.Java注解 什么是注解? 内置注解 元注解 二.对象克隆 什么是对象克隆? 为什么用到对象克隆 三.浅克隆深克隆 一.Java注解 什么是注解? java中注解(Annotation)又称java标注,是一种特殊的注释。 可以添加在包,类&…...
zookeeper的介绍和简单使用
1 zookerper介绍 zookeeper是一个开源的分布式协调服务,由Apache软件基金会提供,主要用于解决分布式应用中的数据管理、状态同步和集群协调等问题。通过提供一个高性能、高可用的协调服务,帮助构建可靠的分布式系统。 Zookeeper的特点和功能…...
【学习笔记】深度学习网络-深度前馈网络(MLP)
作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程,深度学习领域研究生必读教材),开始深度学习领域学习,深入全面的理解深度学习的理论知识。 在之前的文章中介绍了深度学习中用…...
使用Java技术开发软件详细流程
1. 需求分析 与客户沟通:与客户或项目负责人交流,了解需要开发的软件目标、功能需求、性能要求、使用场景等。例如,如果要开发一个在线购物系统,需要明确用户是否可以浏览商品、添加到购物车、下单支付等功能。收集和整理需求&am…...
Kubectl 与 Helm 详解
在 Kubernetes 生态中,kubectl 和 Helm 是两个核心工具,分别用于直接管理 Kubernetes 资源和简化应用的部署与管理。本文将深入探讨 kubectl 和 Helm 的功能、使用场景、部署与更新方式,并对比它们的优缺点。 1. Kubectl 详解 1.1 什么是 Kubectl? kubectl 是 Kubernetes…...
uni-app 程序打包 Android apk、安卓夜神模拟器调试运行
1、打包思路 云端打包方案(每天免费次数限制5,最简单,可以先打包尝试一下你的程序打包后是否能用): HBuilderX 发行App-Android云打包 选择Android、使用云端证书、快速安心打包本地打包: HBuilderX …...
全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析
本文介绍了我在 DOCA 开发环境下对 DPU 进行测评和计算能力测试的一些真实体验和记录。在测评过程中,我主要关注了 DPU 在高并发数据传输和深度学习场景下的表现,以及基本的系统性能指标,包括 CPU 计算、内存带宽、多线程/多进程能力和 I/O 性…...
AI学习(vscode+deepseek+cline)
1、网页生成不成功时,直接根据提示让模型替你解决问题 2、http://localhost:3000 拒绝链接时,cmd输入命令InetMgr,网站右键新建-配置你的网页代码物理地址,这里我还输入本机登录名及密码了,并把端口地址由默认80修改为…...
速通 AI+Web3 开发技能: 免费课程+前沿洞察
AI 正以前所未有的速度重塑各行各业,从生成式模型到大规模数据处理,AI 逐渐成为核心驱动力。与此同时,Web3 去中心化技术也在重新定义信任、交易和协作方式。当这两大前沿技术相遇,AI Web3 的融合已不再是理论,而是未…...
使用LPT wiggler jtag自制三星单片机(sam88 core)编程器-S3F9454
写在前面 新年好,各位,今天来分享制作一个三星单片机的编程器 嘿嘿,x鱼垃圾佬元件库有些三星单片机s3f9454,编程器不想买,基本拿来拆件玩的。但,前些时候csdn下载到它的编程时序,自己来做个编程…...
【Unity3D】《跳舞的线》游戏的方块单方向拉伸实现案例
通过网盘分享的文件:CubeMoveMusic.unitypackage 链接: https://pan.baidu.com/s/1Rq-HH4H9qzVNtpQ84WXyUA?pwda7xn 提取码: a7xn 运行游戏点击空格动态创建拉伸的方块,由Speed控制速度,新方向是随机上下左右生成。 using System.Collect…...
Chameleon(变色龙) 跨平台编译C文件,并一次性生成多个平台的可执行文件
地址:https://github.com/MartinxMax/Chameleon Chameleon 跨平台编译C文件,并一次性生成多个平台的可执行文件。可以通过编译Chameleon自带的.C文件反向Shell生成不同平台攻击载荷。 登录 & 代理设置 按照以下步骤设置 Docker 的代理: 创建配置目…...
解读2025年生物医药创新技术:展览会与论坛的重要性
2025生物医药创新技术与应用发展展览会暨论坛,由天津市生物医药行业协会、BIO CHINA生物发酵展组委会携手主办,山东信世会展服务有限公司承办,定于2025年3月3日至5日在济南黄河国际会展中心盛大开幕。展会规模60000平方米、800参展商、35场会…...
WPF基础 | WPF 布局系统深度剖析:从 Grid 到 StackPanel
WPF基础 | WPF 布局系统深度剖析:从 Grid 到 StackPanel 一、前言二、Grid 布局:万能的布局王者2.1 Grid 布局基础:构建网格世界2.2 子元素定位与跨行列:布局的精细操控2.3 自适应布局:灵活应变的秘诀 三、StackPanel…...
Python从0到100(八十五):神经网络与迁移学习在猫狗分类中的应用
在人工智能的浩瀚宇宙中,深度学习犹如一颗璀璨的星辰,引领着机器学习和计算机视觉领域的前沿探索。而神经网络,作为深度学习的核心架构,更是以其强大的数据建模能力,成为解决复杂问题的重要工具。今天,我们…...
git常用命令学习
目录 文章目录 目录第一章 git简介1.Git 与SVN2.Git 工作区、暂存区和版本库 第二章 git常用命令学习1.ssh设置2.设置用户信息3.常用命令设置1.初始化本地仓库init2.克隆clone3.查看状态 git status4.添加add命令5.添加评论6.分支操作1.创建分支2.查看分支3.切换分支4.删除分支…...
vue中使用jquery 实现table 拖动改变尺寸
使用 CDN , 降低打包文件的大小在index.html中 <script src"https://.../cdns/jquery-1.12.4.min.js"></script>在 Vue 中使用 jQuery 一旦你引入 jQuery,你可以在 Vue 实例中使用它。有两种主要方式: 1. 使用全局变量 $ jQue…...
Linux的基本指令(上)
1.ls指令 语法:ls [选项] [目录或文件] 功能:对于⽬录,该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件,将列出⽂件名以及其他信息。 常用选项: -a 列出⽬录下的所有⽂件,包括以 . 开头的隐含⽂件。 -d 将…...
【单链表算法实战】解锁数据结构核心谜题——相交链表
题目如下: 解题过程如下: 相交链表只可以在中间任意位置/头/尾结点相交,如下图: 一个next指针只能指向一块地址,所以不会出现这种情况: 在返回相交链表的起始结点之前先要判断两个链表是否相交࿰…...
HTTP 配置与应用(不同网段)
想做一个自己学习的有关的csdn账号,努力奋斗......会更新我计算机网络实验课程的所有内容,还有其他的学习知识^_^,为自己巩固一下所学知识,下次更新校园网设计。 我是一个萌新小白,有误地方请大家指正,谢谢…...
深度学习 Pytorch 单层神经网络
神经网络是模仿人类大脑结构所构建的算法,在人脑里,我们有轴突连接神经元,在算法中,我们用圆表示神经元,用线表示神经元之间的连接,数据从神经网络的左侧输入,让神经元处理之后,从右…...
政安晨的AI大模型训练实践三:熟悉一下LF训练模型的WebUI
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 目录 启动WebUI 微调模型 LLaMA-Factory 支持通过 WebUI 零代码微调大语言模型。 启动Web…...
