news 2026/4/18 3:53:50

动态规划DP 自我提问模板

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
动态规划DP 自我提问模板

在面对动态规划问题时,建立一个系统的思考框架能大大提升解题效率。本文以 LeetCode 64 题为例,展示如何用"自我提问模板"梳理 DP 思路,并在实战中验证其有效性。

什么是动态规划自我提问模板?

动态规划的本质是"记忆化递归 + 最优子结构",但很多时候我们会在定义状态、推导转移方程时感到困惑。为了更系统地分析 DP 问题,我总结了一套"自我提问模板",包含以下关键要素:

  1. dp[i][j] 定义:明确每个状态代表什么
  2. 默认值:初始化的边界条件
  3. 外部遍历:如何遍历整个状态空间
  4. choice:在每个状态下有哪些选择(如果适用)
  5. cost:每个选择的代价(如果适用)
  6. 转移条件:什么情况下进行状态转移
  7. 转移方程:如何从子问题推导到当前问题
  8. 返回值:最终答案在状态空间的哪个位置
我的思路 dp[i][j]定义:dp 和 grid 大小相同,dp[i][j]表示对应走到 grid[i][j]的最小sum 默认值:dp[0][0]=grid[0][0]外部遍历:遍历 grid,i 为行,j 为列,跳过 i=0,j=0choice: N/A cost: N/A 转移条件:N/A 转移方程:i=0: dp[i][j]=dp[i][j-1]+ grid[i][j]j=0: dp[i][j]=dp[i-1][j]+ grid[i][j]elsedp[i][j]=min(dp[i][j-1]+ grid[i][j], dp[i-1][j]+ grid[i][j])返回值:dp[gridSize][gridColSize[gridSize -1]]行的最小值

实战案例:LeetCode 64. Minimum Path Sum

题目描述

给定一个 m x n 的网格 grid,每个格子里是一个非负整数。从左上角 (0,0) 出发,只能向右或向下移动,走到右下角 (m-1, n-1)。要求找到一条路径,使路径上所有格子数字之和最小,并返回这个最小和。

使用模板分析

1. dp[i][j] 定义

dp 和 grid 大小相同,dp[i][j] 表示对应走到 grid[i][j] 的最小sum

这个定义很直观:我们需要知道"到达每个格子时的最小路径和",因此 dp[i][j] 就表示从起点 (0,0) 走到位置 (i,j) 的最小路径和。

2. 默认值

dp[0][0] = grid[0][0]

起点是我们的初始状态,它的最小路径和就是起点格子本身的值。

3. 外部遍历

遍历 grid,i 为行,j 为列,跳过 i = 0,j = 0

我们需要填充整个 dp 数组,按行列顺序遍历。由于起点已经初始化,可以跳过 (0,0)。

4. choice & cost

N/A

在这道题中,我们不需要显式地考虑"选择"和"代价"的概念,因为路径是确定性的:只能向右或向下走,没有多个选择需要对比。

5. 转移条件

N/A

这道题的转移是无条件的,每个格子都需要根据其左边和上边的格子更新。

6. 转移方程
i = 0: dp[i][j] = dp[i][j-1] + grid[i][j] // 第一行只能从左边来 j = 0: dp[i][j] = dp[i-1][j] + grid[i][j] // 第一列只能从上边来 else: dp[i][j] = min(dp[i][j-1] + grid[i][j], dp[i-1][j] + grid[i][j]) // 其他位置取左边和上边的最小值

这个转移方程体现了 DP 的核心:

  • 对于第一行(i=0),只能从左边走过来
  • 对于第一列(j=0),只能从上边走过来
  • 对于其他位置,可以从左边或上边过来,我们选择路径和更小的那条
7. 返回值

注意:原始思路写的是"dp[gridSize][gridColSize[gridSize - 1]] 行的最小值",这是错误的!

正确的返回值应该是:dp[gridSize-1][gridColSize[gridSize-1]-1]

即右下角那个格子的值,因为题目要求必须走到右下角,而不是最后一行的任意位置。

C 语言代码实现

#include<stdlib.h>#defineINF_MAX0x7fffffff#defineMIN(a,b)((a)<(b)?(a):(b))intminPathSum(int**grid,intgridSize,int*gridColSize){inti,j,result,col_size;int**dp;// 分配 dp 数组dp=(int**)malloc(gridSize*sizeof(int*));for(i=0;i<gridSize;i++){col_size=gridColSize[i];dp[i]=(int*)malloc(col_size*sizeof(int));for(j=0;j<col_size;j++)dp[i][j]=INF_MAX;// 初始化为最大值}// 设置起点dp[0][0]=grid[0][0];// 遍历整个 gridfor(i=0;i<gridSize;i++){col_size=gridColSize[i];for(j=0;j<col_size;j++){if(i==0&&j==0)continue;// 跳过起点if(i==0)// 第一行:只能从左边来dp[i][j]=dp[i][j-1]+grid[i][j];elseif(j==0)// 第一列:只能从上边来dp[i][j]=dp[i-1][j]+grid[i][j];else// 其他位置:取左边和上边的最小值dp[i][j]=MIN(dp[i][j-1]+grid[i][j],dp[i-1][j]+grid[i][j]);}}// 获取右下角的结果col_size=gridColSize[gridSize-1];result=dp[gridSize-1][col_size-1];// 释放内存for(i=0;i<gridSize;i++)free(dp[i]);free(dp);returnresult;}

模板的价值

通过这个案例,我们可以看到自我提问模板的价值:

  1. 系统性:按照模板逐项分析,不容易遗漏关键要素
  2. 纠错性:在填写"返回值"时,发现了原始思路的错误
  3. 可复用:这个模板可以应用到其他 DP 问题上

当你面对新的 DP 问题时,不妨试试用这个模板梳理思路:

  • 先明确状态定义
  • 找出初始值和边界条件
  • 确定遍历顺序
  • 分析选择和代价(如果有)
  • 推导转移方程
  • 确认返回值

这样的思考流程能帮助你更快地理清思路,写出正确的代码。

总结

动态规划的难点不在于写代码,而在于理清状态和转移的逻辑。通过建立一套自我提问的模板,我们可以:

  • 将复杂问题拆解成可回答的小问题
  • 系统地分析 DP 的各个要素
  • 及时发现思路中的错误

希望这个模板能帮助你在 DP 的道路上走得更顺畅!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 17:38:14

跨设备粘贴板管理工具 CrossPaste

链接&#xff1a;https://pan.quark.cn/s/090985c7351f跨设备的通用粘贴板&#xff0c;在任意设备间复制粘贴&#xff0c;就像在同一台设备上操作一样自然流畅软件特点&#x1f504; 实时共享&#xff1a;设备之间实时共享粘贴板内容&#xff0c;操作自然流畅。 &#x1f5a5;️…

作者头像 李华
网站建设 2026/4/17 1:04:30

网速管家电脑版

链接&#xff1a;https://pan.quark.cn/s/ca6fa7f61bc2网速管家电脑版是一款网络测速软件。软件内置最新版的实时测速功能&#xff0c;一键测速&#xff0c;方便快捷。测速会分为两个部分&#xff0c;下载测速和上传测速&#xff0c;并会得出网络延迟、网速抖动幅度以及是否丢包…

作者头像 李华
网站建设 2026/4/16 21:38:38

java基于SpringBoot的摇滚音乐鉴赏网站的设计与实现-vue

目录摘要关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 该摇滚音乐鉴赏网站…

作者头像 李华
网站建设 2026/3/31 21:47:41

全网最全9个AI论文平台,自考学生轻松搞定毕业论文!

全网最全9个AI论文平台&#xff0c;自考学生轻松搞定毕业论文&#xff01; AI 工具如何成为自考论文写作的得力助手 在当前教育环境中&#xff0c;自考学生面临着时间紧、任务重的压力&#xff0c;尤其是在撰写毕业论文时。而随着 AI 技术的不断发展&#xff0c;越来越多的 AI …

作者头像 李华
网站建设 2026/4/16 16:00:33

一个纯前端的新年倒计时实验合集(已开源)

最近整理并开源了一个小项目合集&#xff1a;New Year Countdown。 这是一些围绕「新年倒计时」这个瞬间做的前端视觉与交互实验&#xff0c;全部基于 纯 HTML / CSS / JavaScript 实现。 项目本身不追求复杂工程化&#xff0c;而是更关注&#xff1a; 时间感 动效节奏 声音…

作者头像 李华