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

路径类 DP 入门:3 道经典例题详解(最小路径和、迷雾森林、过河卒)

路径类动态规划主要解决网格中从起点到终点的方案数或最值问题。本文通过最小路径和、迷雾森林、过河卒三道经典例题,详细拆解了状态定义、转移方程推导及边界处理技巧。重点涵盖了障碍物规避、取模运算及坐标偏移防越界等实战细节,适合初学者系统掌握此类动态规划模型。

开源信徒发布于 2026/3/16更新于 2026/8/2337 浏览
路径类 DP 入门:3 道经典例题详解(最小路径和、迷雾森林、过河卒)

路径类动态规划是线性 DP 的一种常见变体,通常在一个 n × m 的矩阵中设定行走规则,求解从起点到终点的方案数、最小路径和或最大路径和等问题。入门阶段的《数字三角形》其实就属于这一类。

矩阵的最小路径和

题目要求计算从左上角走到右下角的最小路径和。

状态定义 dp[i][j] 表示从 (1, 1) 格子走到 (i, j) 格子时,所有方案下的最小路径和。

状态转移 考虑最后一步,到达 (i, j) 只能从上方 (i-1, j) 或左方 (i, j-1) 过来。因此状态转移方程为: dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + a[i][j]

边界处理 填表时需要访问左边和上边的格子,为了避免越界判断,我们将第 0 行和第 0 列初始化为无穷大。这样在取最小值时,永远不会选中这些无效位置。同时,将 dp[1][1] 初始化为 a[1][1],并在循环中跳过该点,防止被错误覆盖。

实现细节 填表顺序从上往下、从左往右即可。最终结果存储在 dp[n][m] 中。

#include <iostream>
#include <cstring>
using namespace std;

const int N = 510;
int n, m;
int a[N][N], dp[N][N];

int main() {
    // 输入矩阵
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
        }
    }

    // 初始化:第 0 行和第 0 列设为无穷大
    memset(dp, 0x3f, sizeof(dp));
    dp[1][1] = a[1][1];

    // 依序填表
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
             (i ==  && j == ) ;
            dp[i][j] = (dp[i - ][j], dp[i][j - ]) + a[i][j];
        }
    }

    cout << dp[n][m] << endl;
     ;
}
if
1
1
continue
min
1
1
return
0

迷雾森林

这道题求的是从起点到终点的方案数,且只能向上或向右走,遇到树不能通行。

状态定义 dp[i][j] 表示从 (m, 1) 走到 (i, j) 的方案数。

状态转移 根据移动规则,到达 (i, j) 的前一步可能是 (i, j-1) 或 (i+1, j)。如果当前格子是空地(值为 0),则累加前驱状态的方案数;如果是树(值为 1),则方案数为 0。

dp[i][j] = dp[i][j - 1] + dp[i + 1][j] (当 a[i][j] == 0 时)

边界与初始化 由于需要访问左边和下边格子,我们按从下往上、每行从左往右的顺序填表。dp 数组全局定义默认为 0,无需额外 memset。将起点 dp[m][1] 初始化为 1,作为递推的基准。

注意事项 答案需要对 2333 取模,累加过程中要注意溢出问题。

#include <iostream>
#include <stdio.h>
using namespace std;

const int N = 3010;
const int MOD = 2333;
int m, n;
int a[N][N], dp[N][N];

int main() {
    cin >> m >> n;
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    // 起点初始化
    dp[m][1] = 1;

    // 从下往上,从左往右填表
    for (int i = m; i >= 1; i--) {
        for (int j = 1; j <= n; j++) {
            if (i == m && j == 1) continue;
            if (a[i][j] == 0)
                dp[i][j] = (dp[i][j - 1] + dp[i + 1][j]) % MOD;
        }
    }

    cout << dp[1][n];
    return 0;
}

过河卒

卒从 (0, 0) 出发,马控制周围 9 个点,求不经过马控制点的方案数。

坐标偏移技巧 题目强制从 (0, 0) 开始,为了处理数组越界方便,我们将所有输入的坐标统一加 1,相当于棋盘整体平移,从 (1, 1) 开始填表。

状态定义 dp[i][j] 表示从 (1, 1) 走到 (i, j) 的方案数。

状态转移 卒只能向下或向右,方程为: dp[i][j] = dp[i][j - 1] + dp[i - 1][j]

障碍物处理 利用方向向量标记马的控制点。如果某点是马的控制点(包括马本身),则保持 dp 值为 0,不参与累加。

数据类型 方案数增长极快,必须使用 long long 类型存储 dp 数组。

#include <iostream>
using namespace std;

typedef long long LL;
const int N = 25;
int n, m, c, d;
int a[N][N];
LL dp[N][N];

// 马的 8 个控制方向
int dx[8] = {2, 2, 1, 1, -1, -1, -2, -2};
int dy[8] = {1, -1, 2, -2, 2, -2, 1, -1};

int main() {
    cin >> n >> m >> c >> d;
    // 坐标整体 +1,避免边界判断
    n++, m++, c++, d++;

    // 初始化起点
    dp[1][1] = 1;

    // 标记马的控制点
    for (int i = 0; i < 8; i++) {
        a[c + dx[i]][d + dy[i]] = 1;
    }
    a[c][d] = 1;

    // 从左往右,从上往下填表
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (i == 1 && j == 1) continue;
            if (a[i][j] == 0)
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
        }
    }

    cout << dp[n][m] << endl;
    return 0;
}

这三道题涵盖了路径 DP 中最核心的几个考点:边界初始化、取模运算、坐标偏移防越界以及障碍物的特殊处理。掌握这些模式后,面对类似的网格 DP 问题就能快速找到切入点。

目录

  1. 矩阵的最小路径和
  2. 迷雾森林
  3. 过河卒
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Spring Boot 消息队列与异步通信详解
  • Microsoft Visual C++ 运行库安装与修复指南
  • AIGC 工具全解析:文本、图像、代码、视频及音频生成指南
  • 高鋒集團黃俊瑯:資本與生態如何賦能傳統企業 Web3 轉型
  • RRT快速扩展随机树算法详解与Python实现
  • 前端开发中如何准确判断变量非 null 且非 undefined
  • π0 源码剖析:基于 PaLI-Gemma 的扩散策略与 C/S 架构部署
  • AI 推理效率突破:TurboQuant 内存压缩与 RWKV-6 架构优化
  • VSCode Copilot 接入 OpenAI 兼容自定义模型方案
  • Qwen3-VL-WEBUI 视频理解能力实测:256K 上下文部署实战
  • OpenClaw 配置飞书机器人完整指南
  • 清华团队发布 OpenClaw 研究报告:AI 智能体生态闭环解析
  • 开源模型全景图:如何选择你的技术底座
  • 光伏短期功率预测:云图特征提取与云移估计工程方案
  • STM32CubeMX、Keil MDK、Git 及 VS Code 统一 UTF-8 编码配置指南
  • 基于 Skill 与 MCP 的 Spring AI 应用落地:将业务 SOP 转化为 AI 能力
  • AI 与数据驱动下的组织进化:未来三年技术与人才趋势
  • 数字图像处理与 FPGA 实现:搭建算法与硬件思维的桥梁
  • WiFi模块AT指令全解析和智能家居APP制作
  • VSCode 接入 GLM-4 及自定义大模型配置指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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