CalcGuide · 技术博客主页 / 一页纸学习计划
🔥极高

算法设计方法:从递归到动态规划

分类:数据结构与算法 · 路径:docs/topics/algo-design/README.md

#algorithms#recursion#dp#divide-conquer#greedy

用 8~12 周从递归思想到独立设计 DP 状态转移,能解决中等难度的竞赛题

父主题

顶层主题

子主题(4)

算法设计方法:从递归到动态规划

0. 元信息

1. 学习路线

递归调用栈与终止条件
  → 回溯模板(排列 / 组合 / 子集)
  → 贪心:交换论证与反证
  → DP:状态、转移、初始化、压缩
  → 分治:归并、快排、最近点对
  → 状态机抽象:FSM 与 DP / BFS
  → 综合刷题与综合项目

每一步都是下一步的前置。贪心和 DP 都建立在递归思维上,分治和状态机把递归扩展到结构化场景。不要跳级刷题,先把范式想清楚。

2. 阶段周数分配

| 阶段 | 8 周方案 | 12 周方案 | 备注 | ||---:|---:|---| | 1. 递归与回溯 | 1 周 | 1.5 周 | 终止条件 + 调用栈图 | | 2. 贪心 | 1 周 | 1.5 周 | 区间调度、活动选择 | | 3. 动态规划 | 2 周 | 2.5 周 | 状态转移 + 滚动数组 | | 4. 分治 | 1 周 | 1.5 周 | 主定理 + 归并 / 快排 | | 5. 状态机 | 1 周 | 1.5 周 | FSM → DP / BFS | | 6. 综合刷题 + 项目 | 1 周 | 2 周 | 60~120 题 + 1 综合项目 | | 7. 复盘与模拟赛 | 1 周 | 1.5 周 | AtCoder / Codeforces |

8 周方案节奏紧,建议前 5 周固定 12 小时;12 周方案多出的时间做重做和重写。

3. 九阶段表

阶段核心知识实践产出可观察学会标准
1. 递归与回溯调用栈、终止条件、剪枝、排列组合子集8 道回溯题(含 N 皇后、子集、单词搜索)能画递归树、能估算分支因子、能解释为什么剪枝
2. 贪心排序后扫描、交换论证、单调性5~8 道区间 / 调度 / 排序贪心能写出排序贪心并用一句话证明正确性
3. 动态规划状态、转移、初始化、滚动数组15+ DP 题(背包、序列、区间、状压)能独立设计状态,能解释每一维含义,能手写空间优化
4. 分治主定理、递推式、归并、快排、最近点对5 道分治题 + 复述归并快排能写递推式推 T(n)、能讲清楚 merge 与 partition
5. 状态机FSM、转移图、状态压缩、BFS 拓扑序5 道状态机题(含买卖股票、打家劫舍)能把问题画成 FSM、能解释为什么 BFS 拓扑序能算最短转移
6. 综合刷题题型分布、错题本、复盘节奏60~120 道题分类笔记错题重做通过率 ≥80%
7. 综合项目设计一个可演示的算法工具1 个 Python 项目 + README + 复盘他人可按 README 复现
8. 模拟赛限时训练、心态、读题4 场 Codeforces / AtCoder 模拟Div2 2 道题 / ABC 4~5 道题水平
9. 复盘与沉淀错题本、模板库、复盘报告1 份 retrospective.md能讲清自己的强弱项

关键陷阱:贪心没证明就当 DP 解;DP 没画状态转移就硬写;分治忘了合并代价;状态机把”状态”和”动作”混在一起。

4. 第一周任务

Day 1 运行约定:使用 Python 3.10+。统一格式:python -X dev -W error -m py_compile foo.py 做静态检查;运行用 python foo.py < input.txt。代码风格 ruff 默认;测试用 pytest。所有题目代码统一放进 algo-design/week<N>/

任务当天交付
Day 1装 Python 3.11、pytestruff;手写 5 道递归(阶乘、斐波那契、阶乘和、汉诺塔、递归求和);画出每一题的递归调用栈week1/day1/recursion.md 含调用栈图
Day 26 道回溯:全排列、子集、组合总和、电话号码、括号生成、单词搜索week1/day2/backtrack.py + 提交记录
Day 3区间调度 + 活动选择:手写 3 个反例找反证,再写正确版本week1/day3/greedy_intro.py
Day 4DP 入门 5 题:爬楼梯、打家劫舍、最小路径和、零钱兑换、最长递增子序列week1/day4/dp_intro.py
Day 5归并排序 + 计数逆序对;快排 + partition;理解 merge 与 partition 的差别week1/day5/divide.py
Day 6状态机 4 题:买卖股票 I/II(含 cooldown)、打家劫舍 II、状态机版爬楼梯week1/day6/fsm.py
Day 7步骤 A:完成 1 道综合题(如「最长回文子序列」)的完整推导 + 实现;步骤 B:补齐 4 类边界(空串 / 单字符 / 全相同 / 全相反)week1/day7/lps.py + 测试日志

Day 7 步骤 A 把”状态 + 转移 + 初始化 + 输出 + 优化”五段写齐;步骤 B 每次只改一个输入维度。

5. 阶段通用验收

  1. 不看答案独立重写核心代码;
  2. 用自己的话解释该范式”解决什么问题、为什么有效、在哪类题里失效”;
  3. 画一张图:递归树 / 状态转移表 / 分治递推式;
  4. 测试空数据、最小值、最大值、异常输入;
  5. 准备至少 3 组自定义数据并贴出实际输出;
  6. 记录时间复杂度和空间复杂度(含每维含义);
  7. 能修改已有程序(加剪枝 / 改维度 / 换滚动数组),而不是只能照抄。

交付存放:第 3 项的图、第 5 项的输出、第 6 项的复杂度推导,统一存到 week<N>/notes/week<N>/<problem>/README.md

6. 最终验收

7. 综合项目

首选:算法可视化桌面工具(必做:CLI 输入 + 输出 + 可选 GUI)。

备选:自动评测器。从 LeetCode / AtCoder 拉指定题目的测试用例,本地批量跑、对比时间、生成错题本。

备选:算法题模板生成器。给定题型关键词,输出 Python 模板代码(状态定义 / 转移 / 初始化 / 空间优化)。

任何项目都必须包含:

  1. 需求说明;
  2. 数据结构与算法选择理由;
  3. 核心模块说明;
  4. 模块化源码;
  5. 边界测试;
  6. 运行说明(Makefile 或清晰的 python 命令);
  7. README;
  8. 复盘记录。

项目内交付物(设计/测试/复盘)随项目代码放在项目仓库的 notes/design.md / test.md / retrospective.md

8. 推荐开源资料

阶段角色资料链接用法
1~5经典书CLRS《Introduction to Algorithms》https://mitpress.mit.edu/9780262033848/三大范式(分治 / 贪心 / DP)逐章精读
1~5进阶书Udi Manber《Introduction to Algorithms》https://www.cs.arizona.edu/~merlin/Algorithms.pdf递归思维训练,按数学归纳讲
1~5进阶书Knuth《The Art of Computer Programming》Vol.1~4Ahttps://www-cs-faculty.stanford.edu/~knuth/taocp.html拿来当字典,遇到细节再查
1~6刷题平台LeetCodehttps://leetcode.com/题型标签 + 公司标签 + Discussion
1~6刷题平台Codeforceshttps://codeforces.com/模拟赛 + Editorial
3DP 训练AtCoder Educational DP Contesthttps://atcoder.jp/contests/dp26 题系统性 DP 训练
1~6EditorialAtCoder Editorialhttps://atcoder.jp/ABC/ARC/AGC 公开题解
4训练营Petrozavodsk Camphttps://codeforces.com/groups/c3v4QqHRIy高强度团队训练,难题偏多

许可证提示:CLRS 与 Manber 自用学习合理引用;不要复制粘贴 CLRS 课后答案到公开仓库。LeetCode 题面版权见 LeetCode Terms of Service——代码自己写,思路可以分享。

默认使用顺序:先用 LeetCode 按 tag 刷 50 题建立手感 → 跑 AtCoder DP Contest 26 题 → 选读 CLRS 对应章节 → 周末打 Codeforces 模拟赛 → 写复盘到 notes/retrospective.md

9. 学习资料汇聚(v0.3 自包含)

本节由本计划生成。链接指向原始材料或作者公开内容。竞赛平台和题库持续更新,记录时务必写明题目 ID 与比赛日期。

9.1 背景与动机

算法设计方法这门学问成型于 1960 年代末到 1990 年代初。Faigle、Karp、Tarjan 把”整数规划 + 组合”系统化;Bellman 在 1950 年代提出动态规划;Dijkstra、Huffman、Krusal、Prim 把贪心写成可证明的最优解;Knuth 在 TAOCP 里把基础范式和具体算法都做了工程化整理。Cormen、Leiserson、Rivest、Stein 在 1990 年的 CLRS 把这些范式组织成教学体系。

行业位置:算法面试是 FAANG 及国内大厂标配;竞赛选手(Codeforces 红名 / AtCoder 橙名以上)通常对范式切换非常熟练;工程界对算法的需求集中在”用对结构 + 不写明显低效代码”。一句话总结:算法范式决定你能不能把问题抽象出来,编程能力决定你能不能写对实现,两者缺一不可。

9.2 概念地图

核心概念(≥10):

flowchart TB
    Recursion[递归调用栈]
    Backtrack[回溯与剪枝]
    Greedy[贪心 + 交换论证]
    DP[动态规划]
    DivideConquer[分治]
    FSM[有限状态机]
    Memo[memoization / 滚动数组]
    Order[拓扑序 / BFS]
    Recurrence[递推式 + 主定理]
    Permutation[排列 / 组合 / 子集]
    Knapsack[背包 / 序列 / 区间 / 状压]

    Recursion --> Backtrack
    Recursion --> DivideConquer
    Recursion --> Memo
    Memo --> DP
    Backtrack --> Permutation
    Greedy --> DP
    DivideConquer --> Recurrence
    FSM --> DP
    FSM --> Order
    DP --> Knapsack

关系说明:

9.3 基础知识讲解

9.3.1 经典论文

资料影响建议读法
Bellman, On the Theory of Dynamic Programming(1954/1957)DP 起源,刻画”最优性原理”对照今天的状态转移思想读
Dijkstra, A Note on Two Problems in Connexion with Graphs(1959)最短路 + 贪心范式开端跟 Cormen 重述对照看
Huffman, A Method for the Construction of Minimum-Redundancy Codes(1952)贪心构造最优前缀码看证明 + 自己推一遍
Cook, The Complexity of Theorem-Proving Procedures(1971)NP 完全性起点与 Karp 1972 的 21 问题一起读
Karp, Reducibility Among Combinatorial Problems(1972)21 个 NP 完全问题用作”该不该用暴力”的边界
Knuth, The Art of Computer Programming(Vol.1~4A,1968 起)算法工程化百科字典式查

9.3.2 经典书籍

重点读这 5 本。每本都跟一个练习集。

影响用法
Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms(CLRS, 4th ed., 2022)算法课的工业标准三大范式(分治 / 贪心 / DP)逐章精读
Udi Manber, Introduction to Algorithms: A Creative Approach(1989)用数学归纳讲递归把每个算法当归纳证明看
Kleinberg & Tardos, Algorithm Design(2005)范式 + 网络流 + NP 完全与 CLRS 互补,更偏设计思路
Skiena, The Algorithm Design Manual(2nd ed., 2008)工程视角 + 题目反查当”先打哪道题”的指南
Roughgarden, Algorithms Illuminated 系列(2017~2021)CLRS 的可视化替代入门期快速建立直觉

备查:Knuth TAOCP 当字典;Sedgewick 的 Algorithms 当 Java/C++ 实现对照;Halim 的 Competitive Programming 3 当竞赛书。

9.3.3 优秀博客

资料特点用法
CP-Algorithms (e-maxx)几乎所有竞赛算法都有图解 + 代码当作 Cheatsheet;先看英文版
AtCoder Editorial每场 ABC/ARC/AGC 赛后官方题解跟比赛一起读,看标准思路
Codeforces Editorial每场 Round 后的题解与社区讨论复盘比赛失败时找官方 Editorial
labuladong 的算法笔记中文,DP / 回溯 / BFS 框架化讲解当框架字典,但自己先想再对照
USACO Guide美国队训练资料,按难度递进适合做长期刷题路线图

9.3.4 核心人物

人物主要影响建议追踪的材料
Richard BellmanDP 命名 + 最优性原理1954 RAND 报告、Dynamic Programming 1962 书
Donald KnuthTAOCP、Tex、LRU 分析TAOCP Vol.1~4A、Stanford 公开讲座
Tony Hoare快速排序、Hoare 逻辑1960 Quicksort 论文、Communicating Sequential Processes
John Hopcroft算法分析 + 图算法与 Ullman 合著的 The Design and Analysis of Computer Algorithms
Robert TarjanUnion-Find、Splay、强连通分量1983 Turing Award Lecture
Jon Kleinberg网络结构、HITS 算法Algorithm Design(与 Tardos)、NetworkX 案例
Petr MitrichevCodeforces Topcoder 冠军 + 写高质量 EditorialCodeforces 博客、Topcoder 撰稿
Takuya AtCoder (Takahashi)AtCoder 平台 + ABC/AGC 出题风格AtCoder 创始人访谈、AtCoder Magazine

9.3.5 开发方法

方法具体动作何时用
Math induction framing把”算法正确性”写成数学归纳,再写代码分治、回溯、DP 推导
Recursion-tree cost画递归树,数节点与每层代价 → 推 T(n)估算复杂度
State-first design先写状态定义与转移图,再写代码DP、状态机
Greedy counter-example search写贪心后立刻构造反例;找到再换范式任何疑似贪心题
Space optimization ladder从二维 DP → 一维 → 滚动数组 → 状态压缩DP 内存超限时
Editorial-after-attempt30 分钟没思路 → 看 Editorial → 立刻关掉重写避免抄解
Re-do with timer重做错题用计时器,目标是原时长的 50%复盘

9.3.6 重点训练材料(按用途分组)

9.4 经典问题与经典案例

#问题为什么会重要最简答案或图示
1阶乘 / 斐波那契 / 汉诺塔递归三件套;理解调用栈终止条件 + 递推 + 回溯
2全排列 / 子集 / 组合总和回溯模板三连选/不选 + 顺序去重
3N 皇后回溯剪枝极致行级剪枝 + 对角线位运算
4活动选择 / 区间调度贪心经典,按结束时间排序排序后一次扫描
5Huffman 编码贪心 + 优先队列最小堆反复合并最小两节点
60/1 背包 / 完全背包DP 入门 + 空间压缩二维 DP → 一维逆序/正序
7最长公共子序列 (LCS)序列 DP 经典二维 DP,状态是前缀长度
8最长递增子序列 (LIS)一维 DP + 贪心二分DP O(n²) 或 patience sorting O(n log n)
9编辑距离 (Levenshtein)区间 DP + 滚动数组dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+cost)
10矩阵链乘区间 DP 入门dp[l][r] = min over k
11旅行商 (TSP) bitmask状压 DP 入门dp[mask][i] = 走过 mask 停在 i
12归并排序 + 计数逆序对分治模板 + 应用合并时累计 if a[i] > a[j]: cnt += mid - i + 1
13最近点对分治 + 跨带扫描中线两侧 + y 排序后的 7 点扫描
14买卖股票(含 cooldown / 手续费)状态机 DP持有/未持有两状态
15单词拆分 / 子序列匹配FSM BFS 拓扑序状态 = 当前下标;边 = 字典匹配

9.5 学习难点

概念难点

难点为什么会卡突破路径
递归调用栈脑子装不下多层调用用”递推 + 回溯”两步拆;先写终止条件
状态维度的选择DP 该选哪几个维度先写暴力递归 → 找重复子问题 → 压维度
贪心 vs DP 边界不知道该不该用贪心写 DP 后用反例验证贪心
分治与 DP 区别都是递推,但代价不同看子问题是否重叠

思维难点

难点为什么会卡突破路径
设计状态转移想不到递推式把”我做完第 i 步后还剩什么”显式化
找到正确的状态空间状态选多选少都不行画转移图,看每个状态从哪几个状态来
时间复杂度反推不会算递归树数叶子 × 每层代价;用 Master Theorem 验
反例构造贪心看不出反例写完贪心立刻构造 3 个小数据看

工程难点

难点为什么会卡突破路径
Python 递归深度限制1000 层就 RecursionErrorsys.setrecursionlimit(200000);或改写迭代
滚动数组下标越界压缩维度时算错边界画二维表手动填几格再编码
状态压缩位运算bitmask / 子集枚举易写错for mask in range(1<<n) 走一遍调试
测评 TLE / MLE复杂度估算错用 n=100, 1000, 10000 三档估算后再提交

9.6 技术标准与接口

9.6.1 Entity

名称版本 / 文档发布组织状态许可证 / 可访问性
CLRS《Introduction to Algorithms》4th ed., 2022MIT Press主流教材第三方 PDF 公开;纸质与电子书需购买
Knuth TAOCPVol.1~4A 持续更新Addison-Wesley长期工程部分 fascicle 公开 PDF
AtCoder Educational DP Contest26 题固定题库AtCoder永久开放公开题面 + 官方 Editorial
LeetCode 题库持续更新LeetCode订阅制题面按 ToS 使用;代码可分享
Codeforces持续更新Codeforces公开题面公开;Editorial 公开
ICPC / Petrozavodsk Camp每年一届ICPC Foundation / ITMO公开题库题面公开;Editorial 部分公开
CP-Algorithms (e-maxx)持续更新社区活跃CC BY-SA

9.6.2 Scope

9.6.3 Structure

9.6.4 Ecosystem

9.6.5 Depth Tiers

层级能力算法设计主题的可观察标准
L0知道存在知道递归、回溯、贪心、DP、分治、状态机 6 种范式
L1看得懂示例能读别人代码判断用了哪种范式
L2能正确调用能对常见题型直接套模板
L3能解释与排错能独立设计状态、转移与剪枝,并解释复杂度
L4能设计与扩展能设计新题型抽象,或对库做范式分析

本父主题目标是 L3。状态机与高级 DP 可触及局部 L4,但不作为 8~12 周的硬门槛。

9.6.6 Source

10. 常见误区

11. 所有知识点分类(统一规则)

  1. 编程语言
  2. 数据结构与算法
  3. 计算机基础
  4. 工程技术
  5. Web 与后端
  6. 前端与客户端
  7. 数据与人工智能
  8. 项目与职业能力
  9. 安全与可靠性

本计划归属:数据结构与算法 主 + 计算机基础 辅。


直接依赖(1)

查看知识图谱 · 热度 🔥极高