CalcGuide · 技术博客主页 / 一页纸学习计划
🟡

状态机思维:从自动机到 DP 抽象

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

#algorithms#finite-state-machine#dp#bfs#abstraction

能把问题抽象成有限状态机,画状态转移图,写成 DP 或 BFS

父主题

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

子主题(0)

状态机思维:从自动机到 DP 抽象

0. 元信息

1. 学习路线

有限自动机(DFA / NFA)基础
  → 状态、事件、转移、接受态
  → 状态机 → DP:买卖股票 / 打家劫舍
  → 状态机 → BFS:单词接龙 / 拓扑序
  → 多维状态:网格、字符串、图上的 FSM
  → 隐式状态机:把"决策"作为状态
  → 状态压缩 DP(bitmask FSM)

每一步都画状态图。先画图,再写代码。

2. 阶段周数分配

阶段1.5 周方案2 周方案备注
1. FSM 基础0.5 天1 天状态 + 事件 + 转移
2. 状态机 → DP2 天2.5 天122 / 309 / 188 / 213 / 714
3. 状态机 → BFS1.5 天2 天127 / 433 / 752
4. 多维状态 FSM1 天1.5 天487 / 1186 / 903
5. 状态压缩1.5 天2 天526 / 847 / 1434
6. 复盘 + 综合题0.5 天1 天错题重做 + 隐式状态题

每天 1.5~2 小时。1.5 周方案聚焦前 4 阶段;2 周方案多 2 天做状态压缩与综合题。

3. 九阶段表(精简)

3.1 核心知识

3.2 实践产出

3.3 可观察学会标准

4. 第一周(每天 1.5~2 小时)

Day 1 约定:本计划使用 Python 3.10+。统一格式:python -X dev -W error -m py_compile foo.py;测试用 pytest;BFS 模板用 collections.deque。所有代码放进 algo-design/fsm/week<N>/ 目录;每个题目单独 .py 文件,配套 notes/<problem>.md 含状态转移图(节点 = 状态,边 = 事件)、复杂度推导、状态空间估算。

任务当天交付自检
Day 1装 Python 3.11 + pytest + ruff;FSM 入门 2 道:LeetCode 70 爬楼梯(状态机视角)+ 198 打家劫舍(持有 / 不持有两状态)week1/day1/fsm_intro.py + 状态转移图pytest week1/day1/test_fsm.py 2 passed;为 198 题画”持有 / 不持有”两状态转移图
Day 2状态机 DP 入门 3 道:122 买卖股票 II、309 含冷冻期、714 含手续费week1/day2/stock_dp.pypytest week1/day2/test_stock.py 3 passed;LeetCode 3/3 AC;309 题画”持有 / 冷却中 / 可买”三状态图
Day 3状态机 DP 进阶:188 买卖股票 IV(k 笔交易,二维状态 (i, k, hold))、213 打家劫舍 II(环形)week1/day3/stock_advanced.pypytest week1/day3/test_advanced.py 2 passed;LeetCode 2/2 AC;188 题记录状态维度 dp[i][k][hold]
Day 4状态机 BFS 入门 3 道:127 单词接龙、433 最小基因变化、752 打开转盘锁week1/day4/fsm_bfs.py + BFS 状态图pytest week1/day4/test_bfs.py 3 passed;LeetCode 3/3 AC;752 题画 4 位 × 10 种 = 10000 节点的状态空间
Day 5多维状态 FSM 入门:487 最大连续 1 的个数 II(dp[i][k])、1186 删除一次得到子数组最大和week1/day5/multidim_fsm.pypytest week1/day5/test_multidim.py 2 passed;LeetCode 2/2 AC;记录状态维度 dp[i][used]
Day 6状态压缩 DP:526 优美的排列、847 访问所有节点的最短路径week1/day6/bitmask_fsm.pypytest week1/day6/test_bitmask.py 2 passed;LeetCode 2/2 AC;估算 n × 2^n 状态数(n=15 时 491520)
Day 7步骤 A:完成 122 买卖股票 II 的完整状态机推导(两状态 + 转移 + base case + 空间优化到 O(1));步骤 B:补齐 4 类边界(空数组 / 单天价格 / 全跌 / 全涨)week1/day7/stock_ii.py + 4 类边界日志pytest -k test_stock_ii 4 个用例全过;每类边界用例的输入/期望/实际写到 notes/week1-day7.md

Day 7 执行次序

步骤 A —— 买卖股票 II 完整版(60~90 分钟)

  1. 写二维 DP dp[i][hold](i=天数,hold=0/1);
  2. 画状态转移图(两状态);
  3. 压一维 → 滚动变量;
  4. 跑空 / 单天 / 全涨 / 全跌 4 类数据;
  5. 对比 O(n) 空间与 O(1) 空间耗时。

步骤 B —— 4 类边界用例(30~45 分钟)

#用例期望行为验证命令
B1空数组 []返回 0pytest -k test_empty
B2单天价格 [5]返回 0pytest -k test_single
B3全跌 [7,6,4,3,1]返回 0pytest -k test_falling
B4全涨 [1,2,3,4,5]返回 4(差值累加)pytest -k test_rising

Day 7 当天必完成步骤 A;步骤 B 至少完成 B1、B4。

5. 阶段通用验收(精简)

  1. 不看答案重写 10 道 FSM 题;
  2. 用自己的话解释 FSM、DP、BFS 三者关系;
  3. 画出每道题的状态转移图(节点 = 状态,边 = 事件 / 转移);
  4. 测试最小输入、最大输入、特殊情况(空、所有合法、全部非法);
  5. 至少准备 3 组自定义数据贴出实际输出;
  6. 记录每题时间空间复杂度;
  7. 能给现有 FSM 加新状态或新转移。

6. 最终验收

7. 综合项目

首选:状态机算法可视化工具(必做:CLI 输入 + 输出 + 可选 GUI)。
备选:自动评测器(从 LeetCode 拉指定状态机题目的测试用例,本地批量跑、对比时间、生成错题本)。
备选:状态机题模板生成器(给定关键词「买卖股票 / 单词接龙 / 转盘锁」→ 输出 Python 模板)。

状态机算法可视化工具必做要求:

任何综合项目都必须包含:

  1. 需求说明(含输入输出约定);
  2. 数据结构与算法选择理由(为何用状态机 DP、为何选这种状态维度);
  3. 核心模块说明(Solver / Recorder / Renderer 三层);
  4. 模块化源码(每题单独文件 + 公共 base class);
  5. 边界测试(空 / 单元素 / 全跌 / 全涨 + deadends 前置过滤);
  6. 运行说明(Makefile 或清晰的 python -m 命令);
  7. README(项目介绍、运行步骤、目录结构、复盘);
  8. notes/ 规范
文件内容
notes/design.md状态机五元组定义、状态空间估算、算法选型理由
notes/test.md每组测试数据的输入 / 期望输出 / 实际输出 / 通过情况
notes/retrospective.md用时、难点、收获、下一步
notes/state-diagrams/至少 5 道题的状态转移图(手画 + 程序输出 DOT 文件)
notes/dp-tables/至少 3 道 DP 题的状态转移表(手画 + 程序填表截图)
notes/state-space-estimates.md每题的 n × 2^nn × k 状态数估算表
notes/edge-cases.md4 类边界用例的输入 / 期望 / 实际
notes/bfs-vs-dp.md单词接龙(用 BFS)与股票 II(用 DP)的范式对比

本主题贡献

3 职责

  1. 把”当前处境”显式化为 FSM 五元组 (Q, Σ, δ, q0, F) —— Q 是状态集合(持有 / 未持有 / 冷却中 / 已用过 k 笔交易),Σ 是事件集合(价格数组中每天的 ±),δ 是转移函数(买 / 卖 / 持 / 冷),并区分 Moore 机(状态决定输出) 与 Mealy 机(转移决定输出)在买卖股票系题目上的等价转换。
  2. 在 DP / BFS 两种实现路径间切换 —— 求最优解用状态机 DP(买卖股票 / 打家劫舍 / DI 序列),求最短转移步数用 BFS(单词接龙 / 最小基因变化 / 转盘锁);用 guard clause 把 deadends 等非法前置状态在 BFS 入队前过滤(if next_state in deadends: continue),避免把死锁节点加入访问队列。
  3. 用 Trie(前缀树 node[26] 子节点)把单词搜索问题接入 FSM、用 KMP(失败函数 next[] 数组)把”模式匹配”问题接入 FSM;状态压缩时用 bitmask 表示已访问集合(如 526 优美排列 mask & (1<<i)),估算 n × 2^n 状态数(如 n=15 时 491520)作为”该不该用状压”的判断阈值。

4 交付物

  1. 13 道题解(5 状态机 DP + 3 BFS + 3 多维 + 2 状态压缩)+ 4 类边界用例日志(空 / 单天价格 / 全跌 / 全涨)。
  2. 状态机可视化工具(CLI → 状态转移图节点/边表 + DP 转移表每步状态值 + BFS 步数 + deadends 前置过滤后的有效状态空间)。
  3. 至少 5 道题的状态转移图(手画 + DOT 文件:买卖股票 II 的两状态 / 309 含冷冻期的三状态 / 打家劫舍 II 的环形拆两段 / 转盘锁的 10000 节点 / 526 优美排列的 bitmask)落 notes/state-diagrams/ + 至少 3 道 DP 题的状态转移表落 notes/dp-tables/
  4. BFS vs DP 范式对比文档 notes/bfs-vs-dp.md(单词接龙用 BFS 因求最短转移、股票 II 用 DP 因求最大累积收益 —— 同为 FSM 抽象,实现路径由”求最短”还是”求最值”决定)。

3 指标

  1. 20 分钟内独立写出买卖股票 II 的状态机 DP(含 O(1) 空间滚动变量版本,覆盖持有 / 未持有两状态 + 买/卖/持三种转移)。
  2. 把转盘锁的 4 位 × 10 种 = 10000 节点状态空间手画出来(含 deadends 前置过滤后的实际访问节点数估算,证明 BFS 状态空间不是”无限”)。
  3. 在 n=15 时估算 bitmask 状态数 n × 2^n = 491520,主动放弃 bitmask 改用多维 DP 维度(说明状态数估算已成为”该不该用状压”的判断本能,而非盲目开 1<<n)。
阶段角色资料链接用法
1~2抽象Sipser《Introduction to the Theory of Computation》第 1 章https://mitpress.mit.edu/9781133187790/FSM 形式化(Q, Σ, δ, q0, F)
1~2经典CLRS《Introduction to Algorithms》第 4 版第 14、22 章https://mitpress.mit.edu/9780262033848/DP 与 BFS 章节
1~2经典Hopcroft, Motwani, Ullman《Introduction to Automata Theory》https://www.pearson.com/en-us/subject-catalog/p/Pearson-Catalog/p/2000000000FSM 标准教材;当字典
1~3框架labuladong 状态机 DPhttps://labuladong.online/algo/中文框架化讲解;先自己写再对照
1~3图解CP-Algorithms DP + Graphhttps://cp-algorithms.com/英文图解 + 代码;当字典
1~3刷题LeetCodehttps://leetcode.cn/中文题库;状态机按 tag 刷
1~3刷题LeetCode Discuss · 状态机https://leetcode.com/discuss/题目分类讨论
1~3训练USACO Guidehttps://usaco.guide/美国队训练;按难度递进
2范式Halim《Competitive Programming 3》第 4 章https://cpbook.net/竞赛实战;当题目反查
3BFSVisuAlgo BFS 模拟器https://visualgo.net/BFS 状态空间可视化
4协议Kleppmann《DDIA》Ch.9https://dataintensive.net/一致性与共识(含状态机视角)
5bitmaskCP-Algorithms Bitmask 章节https://cp-algorithms.com/位运算 + 子集枚举

许可证提示:CLRS 与 Sipser 自用学习合理引用;不要复制粘贴课后答案到公开仓库。LeetCode 题面版权见 LeetCode Terms of Service——代码自己写,思路可以分享。CP-Algorithms 是 CC BY-SA。默认做法是读思路后自己重写代码,而不是复制 Editorial。

默认使用顺序:先读 Sipser 第 1 章建立 FSM 形式化心智 → 选读 CLRS 第 14、22 章(DP + BFS)→ 用 LeetCode 刷 8 道状态机题(按 tag)→ 用 labuladong / CP-Algorithms 对照 5 道卡住的题 → 实现买卖股票 II / 含 cooldown 完整推导 → 跑 VisuAlgo BFS 模拟器 → 选读 Halim 第 4 章 → 写复盘到 notes/retrospective.md

8. 推荐开源资料

阶段角色资料链接用法
1~2抽象Sipser《Introduction to the Theory of Computation》第 1 章https://mitpress.mit.edu/9781133187790/FSM 形式化(Q, Σ, δ, q0, F)
1~2经典CLRS《Introduction to Algorithms》第 4 版第 14、22 章https://mitpress.mit.edu/9780262033848/DP 与 BFS 章节
1~2经典Hopcroft, Motwani, Ullman《Introduction to Automata Theory》https://www.pearson.com/en-us/subject-catalog/p/Pearson-Catalog/p/2000000000FSM 标准教材;当字典
1~3框架labuladong 状态机 DPhttps://labuladong.online/algo/中文框架化讲解;先自己写再对照
1~3图解CP-Algorithms DP + Graphhttps://cp-algorithms.com/英文图解 + 代码;当字典
1~3刷题LeetCodehttps://leetcode.cn/中文题库;状态机按 tag 刷
1~3刷题LeetCode Discuss · 状态机https://leetcode.com/discuss/题目分类讨论
1~3训练USACO Guidehttps://usaco.guide/美国队训练;按难度递进
2范式Halim《Competitive Programming 3》第 4 章https://cpbook.net/竞赛实战;当题目反查
3BFSVisuAlgo BFS 模拟器https://visualgo.net/BFS 状态空间可视化
4协议Kleppmann《DDIA》Ch.9https://dataintensive.net/一致性与共识(含状态机视角)
5bitmaskCP-Algorithms Bitmask 章节https://cp-algorithms.com/位运算 + 子集枚举

许可证提示:CLRS 与 Sipser 自用学习合理引用;不要复制粘贴课后答案到公开仓库。LeetCode 题面版权见 LeetCode Terms of Service——代码自己写,思路可以分享。CP-Algorithms 是 CC BY-SA。默认做法是读思路后自己重写代码,而不是复制 Editorial。

默认使用顺序:先读 Sipser 第 1 章建立 FSM 形式化心智 → 选读 CLRS 第 14、22 章(DP + BFS)→ 用 LeetCode 刷 8 道状态机题(按 tag)→ 用 labuladong / CP-Algorithms 对照 5 道卡住的题 → 实现买卖股票 II / 含 cooldown 完整推导 → 跑 VisuAlgo BFS 模拟器 → 选读 Halim 第 4 章 → 写复盘到 notes/retrospective.md

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

9.1 背景与动机

有限状态机的数学基础是 Kleene 在 1956 年提出的正则表达式与有限自动机等价定理。Mealy(1955)和 Moore(1956)分别提出 Mealy 机与 Moore 机,把”输出”作为转移的一部分。Rabin & Scott 在 1959 年因 NFA 与 DFA 等价证明获 Turing Award。在算法竞赛里,FSM 思维是 2010 年后逐渐成为中等难度题的常见抽象——把”当前处境”显式化能避开暴力枚举。

行业位置:FSM 是协议设计(TCP / TLS 状态机)、正则表达式(DFA 实现)、游戏 AI(敌人状态切换)、编译原理(词法分析)的核心。算法面试里”买卖股票”系列是 FSM DP 的代表。一句话总结:FSM 思维是把”我做完某件事后处在什么情形”显式化,再按情形做决策或搜索。

9.2 概念地图

flowchart LR
  State[状态]
  Event[事件]
  Transition[转移]
  Accept[接受态]
  DFA[DFA / NFA]
  FSMtoDP[FSM → DP]
  FSMtoBFS[FSM → BFS]
  Multidim[多维状态]
  Bitmask[状态压缩]
  Stock[买卖股票]
  WordLadder[单词接龙]
  Lock[转盘锁]
  TSP[TSP 状压]

  State --> Event
  Event --> Transition
  Transition --> Accept
  DFA --> FSMtoDP
  DFA --> FSMtoBFS
  FSMtoDP --> Multidim
  FSMtoDP --> Bitmask
  Stock --> FSMtoDP
  WordLadder --> FSMtoBFS
  Lock --> FSMtoBFS
  Bitmask --> TSP

核心关系:FSM 是底座抽象;DP / BFS 是两种实现路径;多维状态 + 状态压缩是 FSM 在算法竞赛里的扩展形态。

9.3 基础知识讲解

9.3.1 经典论文

资料影响建议读法
Kleene, Representation of Events in Nerve Nets and Finite Automata(1956)正则表达式与有限自动机等价看历史意义
Mealy, A Method for Synthesizing Sequential Circuits(1955)Mealy 机了解输出作为转移的一部分
Moore, Gedanken-experiments on Sequential Machines(1956)Moore 机与 Mealy 机对照
Rabin & Scott, Finite Automata and Their Decision Problems(1959)NFA / DFA 等价看非确定性证明
Aho, Sethi, Ullman Compilers: Principles, Techniques, Tools(Dragon Book)词法分析用 DFA看正则表达式 → NFA → DFA 构造

9.3.2 经典书籍

影响用法
CLRS 第 4 版第 14 章 Dynamic Programming 与第 22 章 BFSFSM DP 与 BFS 视角当 DP / BFS 章节阅读
Sipser Introduction to the Theory of Computation 第 1 章FSM 形式化当抽象基础
Hopcroft, Motwani, Ullman Introduction to Automata Theory, Languages, and ComputationFSM 标准教材当字典
Halim Competitive Programming 3 第 4 章竞赛实战当题目反查

9.3.3 优秀博客

资料特点用法
labuladong 状态机 DP中文框架当 Cheatsheet
CP-Algorithms DP + Graph英文图解当字典
LeetCode Discuss · 状态机题目分类讨论看官方 Editorial 优先
AtCoder Editorial题目抽象讲解跟比赛读

9.3.4 核心人物

人物主要影响建议追踪的材料
Stephen Kleene正则表达式与 FSM 等价1956 论文
George Mealy / Edward MooreMealy / Moore 机1955 / 1956 论文
Michael Rabin / Dana ScottNFA / DFA 等价证明1959 论文,1976 Turing Award
John Hopcroft / Jeffrey Ullman自动机理论教材三人合著《自动机理论》
楼天城(楼教主)竞赛圈”状态机思维”实战Codeforces / Topcoder 题解

9.3.5 开发方法

方法具体动作何时用
State-first先列出所有状态,再写转移任何 FSM 题
Transition-diagram画有向图:节点 = 状态,边 = 事件FSM 入门
DFS-vs-BFS choice状态空间小 → DFS;求最短 → BFSFSM 实现路径
Multidim explosion维度乘积太大时考虑降维复杂 FSM
Implicit-state search把”决策”作为状态的一部分决策类问题
BFS-on-implicit-graph把所有合法中间结果当作节点单词接龙 / 转盘锁

9.4 经典问题与经典案例

#问题为什么重要最简答案或图示
1LeetCode 122 买卖股票 IIFSM DP 入门两个状态:持有 / 未持有
2LeetCode 309 含冷冻期三状态 FSM持有 / 未持有(冷却中)/ 未持有(可买)
3LeetCode 188 买卖股票 IVk 笔交易 FSM二维状态 (i, k, hold)
4LeetCode 213 打家劫舍 IIFSM 环形版分两段:偷第一家 / 不偷第一家
5LeetCode 127 单词接龙FSM BFS状态 = 单词;边 = 差一个字母
6LeetCode 433 最小基因变化FSM BFS状态 = 基因串;边 = 一个字母变化
7LeetCode 752 打开转盘锁FSM BFS状态 = 4 位数;边 = ±1 或死锁过滤
8LeetCode 487 最大连续 1 II多维 FSMdp[i][k] = 在 i 位置已用 k 次翻转的最长
9LeetCode 903 DI 序列有效排列隐式 FSM DP状态 = 当前 i 与栈深;转移看插入 D / I
10LeetCode 526 优美排列状态压缩 DP状态 = bitmask 表示已用数字

9.5 学习难点

概念难点

难点为什么会卡突破路径
状态识别不知道该选哪几个状态把”我做完某件事后处在什么情形”列出来
DFA vs NFA选错实现NFA 转 DFA 用子集构造;DP 通常是 DFA
Moore vs Mealy输出在哪一步Moore:状态决定输出;Mealy:转移决定输出

思维难点

难点为什么会卡突破路径
多维状态爆炸状态数 = 维度乘积降维:合并等价状态;用单调性剪枝
隐式状态题目没说”状态”二字把决策、约束、资源都画成状态
转移设计不知道事件有哪些把”每一步能做的合法操作”列出来
状态压缩选择不知道用 bitmask 还是 DP 维度估算状态数:n=20 用 bitmask,n=100 用 DP 维度

工程难点

难点为什么会卡突破路径
BFS 队列爆状态空间太大加 visited;用双向 BFS
DP 状态数太大状态数 = n × k × 2加剪枝;降维;用记忆化
bitmask 操作错误位运算写错(1 << i) & mask、`mask
转盘锁死锁跳过 deadends 失败BFS 前先把 deadends 加到 visited

9.6 技术标准与接口

9.6.1 Entity

名称版本 / 文档发布组织状态许可证 / 可访问性
CLRS 第 4 版2022MIT Press主流教材第三方 PDF 公开
Sipser《Theory of Computation》第 3 版2012Cengage主流教材第三方资源公开
Python collections.dequeCPython 3.10+PSF内建PSF License
regex(DFA 实现)re2 / PCRE各实现活跃BSD / PCRE LICENSE

9.6.2 Scope

9.6.3 Structure

9.6.4 Ecosystem

9.6.5 Depth Tiers

层级能力状态机思维的可观察标准
L0知道存在知道 FSM 是显式化”当前处境”
L1看得懂示例能读懂别人的状态机代码
L2能正确调用能写买卖股票 / 单词接龙
L3能解释与排错能设计新题的状态空间,选择 DP 或 BFS
L4能设计与扩展能把复杂问题抽象成 FSM 并优化状态数

本子主题目标:L3。能画状态转移图 + 选择正确实现路径 + 解释空间复杂度即达到。

9.6.6 Source

10. 常见误区


11. 所有知识点分类

  1. 编程语言(辅):Python collections.deque 做 BFS、functools.lru_cache 做 FSM DP memo、位运算 (1<<imask | (1<<i)mask & ~(1<<i))、set 做 BFS visited、re 模块(DFA 实现正则)。
  2. 数据结构与算法(主):FSM 五元组(Q, Σ, δ, q0, F)、DFA / NFA、Mealy / Moore 机、状态机 → DP(买卖股票 / 打家劫舍)、状态机 → BFS(单词接龙 / 转盘锁)、多维状态、状态压缩(bitmask FSM)。
  3. 计算机基础:正则表达式与有限自动机等价、词法分析(正则 → NFA → DFA 子集构造)、协议状态机(TCP / TLS)、NFA → DFA 转换的子集构造法。
  4. 工程技术:画状态转移图(节点 = 状态,边 = 事件)、估算 n × 2^n 状态数选 DP 或 BFS、双向 BFS 缩小搜索空间、deadends 等非法状态前置过滤。
  5. Web 与后端:HTTP 协议状态机、TCP 连接状态、正则路由匹配(DFA);本计划不展开。
  6. 前端与客户端:浏览器事件循环的状态视角、表单状态机;本计划不展开。
  7. 数据与人工智能:HMM / CRF 序列标注本质是 FSM;本计划不展开。
  8. 项目与职业能力:LeetCode 122 / 127 / 188 / 213 / 309 / 433 / 487 / 752 / 903 等 FSM 高频面试题、20 分钟写出买卖股票 II 状态机 DP、估算状态空间选择 DP 或 BFS。

本计划归属:数据结构与算法 主 + 编程语言 辅。


直接依赖(1)

查看知识图谱