news 2026/9/30 15:56:15

区间DP 模板总结(递推版 / 记忆化搜索版通用伪代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
区间DP 模板总结(递推版 / 记忆化搜索版通用伪代码)

区间 DP(interval DP)的核心,就是“状态 = 一个区间”,“转移 = 把区间拆成左右两个子区间再合并结果”。oi-wiki+1​
下面用模板化的方式讲一遍:什么时候想到区间 DP、怎么设计状态与转移,以及常见两种代码写法(递推版 / 记忆化搜索版伪代码)。cnblogs+1​


典型特征与建模套路

区间 DP 适用的一般特征:dotcpp+1​

问题在一个序列上,要求的是“某一段连续子区间”的最优值(最大 / 最小 / 方案数等)。
能把一个区间 [l,r][l,r][l,r] 的决策拆成“枚举中间断点 kkk”,再由两边子区间 [l,k][l,k][l,k]、[k+1,r][k+1,r][k+1,r] 的答案合并得到 [l,r][l,r][l,r] 的答案。
子区间必须是连续的,且大区间必然由更小区间组合而成。

常见例子:石子合并、矩阵链乘、戳气球、回文子串分割等,本质上都是“枚举断点拆区间 + 合并子问题”。csdn+1​

抽象模型(极其常用的那种):oi-wiki+2​

状态:

dp[l][r]dp[l][r]dp[l][r]:表示处理区间 [l,r][l,r][l,r] 时的最优值。

转移:

在区间 [l,r][l,r][l,r] 内枚举一个“分割点” kkk,把区间拆成两部分:[l,k][l,k][l,k]、[k+1,r][k+1,r][k+1,r]。
然后用某个“合并代价 / 合并收益”把两边结果加在一起:
例如:

dp[l][r]=min⁡l≤k<r{dp[l][k]+dp[k+1][r]+mergeCost(l,r,k)}dp[l][r] = \min_{l \le k < r} \{dp[l][k] + dp[k+1][r] + \text{mergeCost}(l,r,k)\}dp[l][r]=l≤k<rmin{dp[l][k]+dp[k+1][r]+mergeCost(l,r,k)}

边界:

通常长度为 1 的区间(单个元素)容易直接给出:如合并代价 0、收益等。

枚举顺序:

必须保证在计算 [l,r][l,r][l,r] 之前,所有更短的子区间已经计算过。


递推版通用伪代码模板(长度枚举)

这是最常见、最标准的区间 DP 写法,用“区间长度从小到大”的顺序枚举:csdn+2​

// n 个元素,下标 1..n // dp[l][r]:区间 [l, r] 的最优值 // 初始化 for l in 1..n: dp[l][l] = base_value_of_single(l) // 视题目而定,例如 0 或 a[l] 等 // 区间长度从 2 开始(至少两个元素才需要合并) for len in 2..n: // len = 区间长度 for l in 1..n-len+1: // 枚举左端点 r = l + len - 1 // 确定右端点 dp[l][r] = +INF or -INF or 0 // 根据是求最小 / 最大 / 计数初始化 // 在 [l, r-1] 枚举分割点 k for k in l..r-1: // 左右子区间 [l, k], [k+1, r] 一定已经被算过 candidate = dp[l][k] + dp[k+1][r] + merge_cost(l, r, k) dp[l][r] = better(dp[l][r], candidate) answer = dp[1][n]

说明要点:dotcpp+1​

外层 len 从小到大,保证用到的子区间都是“长度更短”的。
中间 l 枚举左端点,r 由 len 推出。
最内层 k 是断点,一般是 l…r-1。

merge_cost(l,r,k) 根据题目不同,可能是:

区间权值和,如石子合并用前缀和 sum[r] - sum[l-1]。csdn+1​
与元素值相关的乘积等,如戳气球那种 a[l-1]*a[k]*a[r+1]。csdn​

better() 是 min / max 或 “加法 + 取模”等,视题目目标而定。

如果是“最大值 DP”,只需把初始化和 better 换成对应的最大化即可,例如:dp[l][r] = -INF; dp[l][r] = max(dp[l][r], candidate)。csdn+1​


记忆化搜索版通用伪代码模板(递归写法)

同一个思想可以写成递归 + 记忆化(有时思路更直观):cnblogs+1​

// n 个元素,下标 1..n // dp[l][r]:区间 [l, r] 的最优值,初值为 UNKNOWN (例如用 -1 或特定 flag 表示未计算) function solve(l, r): if l == r: return base_value_of_single(l) // 区间长度 1 的边界 if dp[l][r] is not UNKNOWN: return dp[l][r] best = +INF or -INF or 0 // 初始化 for k in l..r-1: // 枚举分割点 left = solve(l, k) right = solve(k+1, r) candidate = left + right + merge_cost(l, r, k) best = better(best, candidate) dp[l][r] = best return best answer = solve(1, n)

说明要点:cnblogs+1​

递归深度为 O(n)O(n)O(n),调用次数为 O(n2)O(n^2)O(n2),每次枚举 O(n)O(n)O(n) 个断点,总复杂度仍然是 O(n3)O(n^3)O(n3)(和递推版同级)。
思维过程上更贴近“把大区间拆成左右两个子区间”的问题分析方式。


模板中常见的细节与变形

1. 初始化与无效值

若求最小值:

dp[l][r] 初始化为一个足够大的数(如 INF);better 用 min。dotcpp+1​

若求最大值:

dp[l][r] 初始化为一个足够小的数(如 -INF);better 用 max。csdn+1​

若是计数型(方案数):

一般初始化为 0,然后累加方案数。

2. 环形区间(例如环形石子合并)

常见套路:把序列复制一遍,变成长度 2n2n2n 的线性序列,然后在所有长度为 nnn 的区间里取最优值即可。dotcpp+1​

伪代码骨架(求某种最优值):csdn+1​

// 将 a[1..n] 复制到 a[n+1..2n] for i in 1..n: a[i + n] = a[i] // 按照普通区间 DP 在 1..2n 上做 for each valid len, l, r in [1..2n]: // 同前面模板计算 dp[l][r] // 最终答案是在所有长为 n 的区间中取最优 ans = +INF or -INF for l in 1..n: r = l + n - 1 ans = better(ans, dp[l][r])

这里的内部转移依旧是标准区间 DP 模板,只是定义的有效区间范围变成了 [1…2n]。dotcpp+1​

3. 不止两个子区间的情况

有些题要“先分成三段 / 多段,再合并”,本质上仍然是:一个区间的状态只依赖于更小的若干子区间,可以通过扩展转移时的枚举方式来实现,例如先枚举第一个断点、再枚举第二个断点,仍然是长度从小到大的外层顺序。整体思路不变,只是转移式多了一层循环。


一眼看出是区间 DP 的判断思路

碰到题目时,可以对照下面的 checklist 判断是否可以上“区间 DP 模板”:csdn+2​

题目给的是一段线性序列(或环形,但可以展开成线性)。
问的是“整段区间”或“某个子区间”的最优值,而不是固定从左到右一步步做决策。
决策方式很像“把区间断成两半处理”,并且每次处理只和相邻子区间有关。
能自然写出 “[l,r][l,r][l,r] 的答案由 [l,k][l,k][l,k]、[k+1,r][k+1,r][k+1,r] 推出来” 的递推式。

如果能写出这样的递推式,自然就可以直接套上面这两套伪代码模板(递推版 or 记忆化版),只需要具体填好三件事:

base_value_of_single(l)
merge_cost(l, r, k)
better() 是 min / max / + 等

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

Qwen3-VL将PPT截图转换为演讲稿大纲

Qwen3-VL如何将PPT截图智能转化为演讲稿大纲 在现代办公场景中&#xff0c;我们经常面临一个看似简单却耗时费力的任务&#xff1a;把一份结构清晰但内容密集的PPT转换成适合口头表达的演讲稿。尤其是当这些幻灯片来自不同人、风格各异、图文混排复杂时&#xff0c;手动逐页整理…

作者头像 李华
网站建设 2026/9/29 8:56:00

Qwen3-VL解析BML Full-Stack全流程建模

Qwen3-VL 与 BML Full-Stack&#xff1a;重塑多模态建模的边界 在智能技术加速渗透日常的今天&#xff0c;一个现实问题日益凸显&#xff1a;如何让强大的AI模型真正“可用”&#xff1f;不是仅限于实验室中的演示&#xff0c;也不是依赖高配GPU和复杂环境配置的“专家特权”&a…

作者头像 李华
网站建设 2026/9/30 12:08:38

Qwen3-VL读取百度飞桨AI Studio算力消耗

Qwen3-VL在百度飞桨AI Studio上的算力使用与多模态实践 在智能开发门槛不断降低的今天&#xff0c;一个开发者只需点击几下鼠标&#xff0c;就能运行拥有数十亿参数的视觉-语言大模型。这种变化的背后&#xff0c;是国产大模型技术与云端AI平台深度协同的结果。以通义千问团队推…

作者头像 李华
网站建设 2026/9/29 8:56:00

Qwen3-VL解析Kaggle竞赛页面规则说明

Qwen3-VL如何“读懂”Kaggle竞赛页面&#xff1f; 在数据科学竞赛的世界里&#xff0c;Kaggle早已成为全球开发者和研究者的竞技场。然而&#xff0c;真正参与过比赛的人都知道&#xff1a;比建模更耗时的&#xff0c;往往是读完那几十页密密麻麻的比赛规则。 滚动条拉到底都未…

作者头像 李华
网站建设 2026/9/28 20:27:45

ST-Link ARM仿真器时钟配置:精准调试系统时序

ST-Link时钟配置实战&#xff1a;如何让调试不再“卡顿”&#xff1f;你有没有遇到过这样的场景&#xff1f;代码明明逻辑正确&#xff0c;但一进调试模式就断连&#xff1b;变量刷新慢得像幻灯片&#xff0c;单步执行要等半秒才响应&#xff1b;甚至设置个断点&#xff0c;系统…

作者头像 李华