跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

动态规划路径问题入门:核心定义与 LeetCode 例题解析

介绍动态规划中的路径类问题,涵盖核心定义、无后效性、重叠子问题及最优子结构三大特征。详细阐述动态规划五步法:状态表示、转移方程、初始化、填表顺序及返回值。通过 LeetCode 62 不同路径、63 不同路径 II 及 LCR 166 珠宝最高价值三道经典例题,演示如何应用动态规划解决网格路径计数、避障路径及最大路径和问题,提供 C++ 代码实现。

虚拟内存发布于 2026/3/29更新于 2026/7/2047 浏览
动态规划路径问题入门:核心定义与 LeetCode 例题解析

1. 什么叫路径类动态规划

路径类动态规划是动态规划的一个重要分支,核心解决'从起点到终点的路径相关问题'——比如'路径总数''最短路径长度''路径上的最大/最小和'等,其本质是通过'状态递推'避免重复计算,高效求解多阶段决策的路径问题。

核心定义(通俗理解)

把问题想象成'走迷宫':

  • 起点:初始状态(如网格的左上角);
  • 终点:目标状态(如网格的右下角);
  • 路径:从起点到终点的每一步选择(如只能向右/向下走);
  • 约束条件:每一步的限制(如不能走障碍物、只能走特定方向);
  • 目标:求路径的数量、最短距离、最大收益等。

动态规划的核心是'记住每一步的结果':比如走到网格的 (i,j) 位置时,已有的路径数/最短距离,后续计算无需重复推导,直接基于前面的结果递推。

PS:一般来说,路径类的问题不仅可以用动态规划,还可以使用 BFS 和 DFS。

核心特征(识别这类问题的关键)

  1. 无后效性:走到 (i,j) 的路径只和'之前的步骤'有关,和'之后的步骤'无关(比如走到 (i,j) 有 5 条路径,不管之后怎么去终点,这 5 条路径的数量是固定的);
  2. 重叠子问题:从起点到不同位置的路径会重复经过某些中间状态(比如走到 (i,j) 可能需要先经过 (i-1,j) 或 (i,j-1),这两个状态的路径数需要反复用到);
  3. 最优子结构:如果求'最短路径',那么走到 (i,j) 的最短路径,一定是从 (i-1,j) 或 (i,j-1) 的最短路径中选更优的那个(子问题的最优解能推出原问题的最优解)。

2. 动态规划步骤

状态表示

状态表示就是我们数组对应的那个位置的值的含义,简单来说就是那个值代表着什么。比如说我们前面说的前缀和,那他的状态表示就是代表着原数组前面这些数的累加。

状态转移方程

状态转移方程就是根据上面的状态表示来得到的一个公式,比如说我们前面说的前缀和,它的状态转移方程就是 dp[i]=dp[i-1]+nums[i]。

初始化

初始化的作用简单来说就是为了防止数组越界访问,所以我们在一开始会给 dp 表的一小部分值提前给好。方便我们后续计算。拿前缀和来说就是第 0 个位子我们会直接给 0。

填表顺序

之所以我们要有填表顺序,是因为我们填当前位置的值会使用到前面的一些值,那么我们要确保前面的这些值都已经计算好了。

返回值

返回值就是返回题目要求的那个值。

3. 例题讲解

3.1 LeetCode 62. 不同路径

我们来看这道题,题目就是要求我们在一个二维数组里面,计算机器人从左上角走到右下角的路径总数。

文章配图

所以在这道题里面它的状态表示就是走到当前位置的路线数。

所以在这道题里面它的状态转移方程就是 dp[i][j]=dp[i-1][j]+dp[i][j-1];

说明:我们在这里需要明白为什么是相加,这是因为题目里面说到达这个位置的方式只有上面和右边,那么我们到达该位置的数量就是这两个位置的相加。

我们在这边需要多设置一行一列,它的初始化就是在把虚拟位置的 [0][1] 给设置为 1.

说明:这边之所以这么设置是因为当前位是需要它上面的和左边的值。如果不这样设置的话,就会发生越界访问。(当然我们也可以不设置,直接把原本的第 0 行和第 0 列全部设置为 1,这样也是可以的。但是不推荐这样写,因为现在这些题目都是简单题,如果遇到一些难的题目的话,就会理不清了,所以建议还是多设置一行一列)

填表顺序就是一行一行的填写。

返回值就是 dp[m][n]。

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        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.2 LeetCode 63. 不同路径 II

这道题目的话和上面那一道题目很像,都是在一个二维数组里面,计算机器人从左上角走到右下角的路径总数。唯一的区别就是这道题给的数组里面是存在石头的,也就是需要机器人绕路的点。

文章配图

所以在这道题里面它的状态表示就是走到当前位置的路线数。

所以在这道题里面它的状态转移方程就是 dp[i][j]=dp[i-1][j]+dp[i][j-1],如果遇到石头的话就是 0。

我们在这边需要多设置一行一列,它的初始化就是在把虚拟位置的 [0][1] 给设置为 1.

填表顺序就是一行一行的填写。

返回值就是 dp[m][n]。

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& ob) {
        int m=ob.size();
        int n=ob[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        dp[0][1]=1;
        for(int i=1;i<=m;++i) {
            for(int j=1;j<=n;++j) {
                if(ob[i-1][j-1]==1) dp[i][j]=0;
                else dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[m][n];
    }
};

3.3 LeetCode LCR 166. 珠宝的最高价值

这道题的话和前面两道题目不太一样,题目是要求我们到达右下角时整个途中经过的数组数字和最大。

文章配图

这道题的话是带着一点贪心的思想在里面的,我们在设计代码的时候也是同样的,就是要让 dp 表里面的每一个位置都是代表走到这个位置时所能达到的最大值。

所以在这道题里面它的状态表示就是走到当前位置时能达到的最大值。

所以在这道题里面它的状态转移方程就是 dp[i][j]=max(dp[i-1][j],dp[i][j-1])+f[i-1][j-1]。

(+f[i-1][j-1] 是因为还需要加上当前位置的值,也就是走到这个位置时的自身值)

我们在这边需要多设置一行一列,它的初始化就是在把虚拟位置的 [0][1] 给设置为 1.

填表顺序就是一行一行的填写。

返回值就是 dp[m][n]。

class Solution {
public:
    int jewelleryValue(vector<vector<int>>& f) {
        int m=f.size();
        int n=f[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        dp[1][1]=f[0][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])+f[i-1][j-1];
            }
        }
        return dp[m][n];
    }
};

目录

  1. 1. 什么叫路径类动态规划
  2. 核心定义(通俗理解)
  3. 核心特征(识别这类问题的关键)
  4. 2. 动态规划步骤
  5. 状态表示
  6. 状态转移方程
  7. 初始化
  8. 填表顺序
  9. 返回值
  10. 3. 例题讲解
  11. 3.1 LeetCode 62. 不同路径
  12. 3.2 LeetCode 63. 不同路径 II
  13. 3.3 LeetCode LCR 166. 珠宝的最高价值
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenTenBase 企业级分布式 HTAP 数据库部署实战
  • Ubuntu 系统下使用 VSCode 编写运行 C++ 程序及 Make CMake 编译配置
  • Elasticsearch 核心概念与 Java 客户端实战
  • Python 技能实战:从自动化办公到数据分析的职业进阶
  • C++ 基于哈希表封装 unordered_map 与 unordered_set 模拟实现
  • VSCode Copilot 登录失败的常见原因与排查方案
  • Dify 工作流集成 Sambert-Hifigan 语音合成 API 实现对话机器人
  • 前端请求后端 404/405/500 状态码排查与解决指南
  • 提示词工程:大语言模型指令设计与优化
  • Neo4j Desktop 安装与使用指南:本地实例、远程连接及数据导入
  • Moon VR Video Player 使用教程:支持 8K/12K 多音轨与外挂字幕
  • C++ 智能指针详解:原理、实现与内存管理最佳实践
  • this、箭头函数与普通函数:前端实战避坑指南
  • .NET WebApi 项目必要配置项详解
  • VLM Unlearning 技术路线论文综述
  • AI 绘画实战指南:从提示词到高质量图像生成
  • 大模型基础知识:分词与提示工程详解
  • 2025 AI IDE 全面对比:Trae、Copilot、Windsurf、Cursor 谁值得个人开发者入手?
  • AIGC 个性化与定制化内容生成:技术与应用
  • Qwen3-VL 视觉模型微调实战:LLaMA-Factory 与 WEBUI 部署

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online