算法札记:Dilworth定理及其证明(导弹拦截)

📅 2026/6/22 6:52:59
算法札记:Dilworth定理及其证明(导弹拦截)
Dilworth定理想象一下你正坐在一个防空指挥室里雷达屏幕上密密麻麻全是敌方导弹的光点每个导弹都有一个飞行高度。你的任务就是用最少的拦截系统把这些导弹全部打下来。但这里有个麻烦的规则‌每一套拦截系统它打出的导弹高度必须是一发比一发低或者至少不能越来越高‌。也就是说一套系统只能拦截一个“不上升”的高度序列。问题来了最少需要多少套系统直觉上我们可能会想用贪心算法来一枚导弹就看看现有系统里谁能拦截它就塞给谁如果都不行就新开一套系统。这个方法其实是对的但它并没有告诉你这个“最少”的数量到底是由什么决定的。‌Dilworth定理就像一道闪电瞬间照亮了答案。‌定理到底说了什么用大白话讲Dilworth定理在导弹拦截这个场景里就是说了一句“废话”但又是一句极其深刻的“废话”‌“你最少需要多少套拦截系统恰好等于你导弹序列里那个‘最长上升子序列’的长度。”‌是不是有点绕别急我们拆开来看。‌“链”‌在我们的问题里就是‌一套拦截系统能拦截的所有导弹‌。因为它们的高度是“不上升”的所以它们之间可以互相比较谁高谁低这就构成了一条“链”。‌“反链”‌就是‌一串导弹它们的高度是严格上升的‌。为什么叫“反链”因为在这串导弹里任意两枚都无法被同一套系统拦截后一枚总比前一枚高违反了“不高于前一发”的规则它们之间“不可比较”所以叫“反链”。现在定理的核心就变成了‌“最少链的划分最少系统数” “最长反链的长度最长上升子序列长度”‌用例子说话一看就懂假设导弹按顺序飞来高度是[3, 1, 4, 2]我们先来找找它的‌最长上升子序列‌。可能的上升序列有[3, 4][1, 4][1, 2]最长上升子序列的长度是 ‌2‌比如[1, 2]或[3, 4]。根据Dilworth定理我们最少需要的拦截系统数量就应该等于这个长度也就是 ‌2套‌。我们来验证一下看看是不是真的需要2套系统‌第1套系统‌拦截了第1枚导弹高度3然后它只能拦截高度 ≤ 3 的导弹。第2枚导弹高度1可以拦截。所以这套系统拦截了[3, 1]。‌第2套系统‌第3枚导弹高度4第1套系统刚拦截了高度1没法拦截高度4因为4 1违反了不上升规则。所以必须新开一套系统拦截高度4。接着第4枚导弹高度2它 ≤ 4可以被第2套系统拦截。所以这套系统拦截了[4, 2]。你看正好2套系统一套不多一套不少。为什么这个定理如此神奇它的美妙之处在于它把一个‌“最少需要多少”的划分问题‌巧妙地转化成了一个‌“最长能有多长”的寻找问题‌。你不需要费尽心思去模拟怎么分配系统只需要找出那个最长的、节节攀升的导弹序列它的长度就是你要的答案。因为在这个最长上升序列里的每一枚导弹都注定无法和序列里的其他任何一枚共享同一套拦截系统它们就像一群死对头必须一人一间牢房。所以这个最长上升序列的长度就是你牢房数量的下限而Dilworth定理告诉你这个下限恰好就能达到证明准备工作把概念精确化在开始证明前我们先把“导弹拦截”里的直觉翻译成精确的数学语言。我们有一个‌有限偏序集‌ (P,≤)。这里的“偏序关系” ≤ 满足自反性、反对称性和传递性。‌链‌P 的一个子集其中任意两个元素都是可比的。在导弹问题中一套系统拦截的导弹序列高度不上升就是一条链。‌反链‌P 的一个子集其中任意两个不同元素都不可比。在导弹问题中一个高度严格上升的导弹序列就是一条反链。‌链划分‌把 P 分成若干条互不相交的链这些链的并集就是整个 P。我们关心的是‌最小链划分数‌即最少需要多少条链才能覆盖整个 P。‌最长反链‌P 中包含元素最多的反链其元素个数记为 w。我们的目标是证明‌最小链划分数 最长反链的元素个数 w‌。第一步证明“最小链划分数 ≥ 最长反链长度 w”这一步非常直观是证明的“容易”部分。设 A 是 P 中一个元素个数为 w 的最长反链。根据反链的定义A 中的任意两个元素都不可比。这意味着在任何一个链划分中A 中的任意两个元素都‌不能‌被放入同一条链因为同一条链里的元素必须两两可比。因此A 中的 w 个元素每一个都必须独占一条不同的链。所以任何链划分至少需要 w 条链。那么最小链划分数也必然大于或等于 w。 ‌结论‌最小链划分数 ≥w。第二步证明“最小链划分数 ≤ 最长反链长度 w”这是证明的核心和难点。我们需要证明确实存在一种划分方法恰好只用 w 条链就能覆盖整个 P。我们对偏序集 P 的元素个数 ∣P∣ 进行‌数学归纳‌。‌归纳基础‌当 ∣P∣1 时结论显然成立。此时最长反链长度 w1整个集合本身既是1条链也是1个反链用1条链即可覆盖。‌归纳假设‌假设对于所有元素个数小于 ∣P∣ 的有限偏序集定理成立。‌归纳步骤‌现在考虑元素个数为 ∣P∣ 的偏序集。设 A 是 P 的一条最长反链长度为 w。我们分两种情况讨论。情况一存在一条最长反链 A它既不是 P 的所有极大元的集合也不是 P 的所有极小元的集合这意味着在 A 之外既有比 A 中某些元素大的元素也有比 A 中某些元素小的元素。我们定义两个集合‌上集‌ U(A){x∈P∣∃a∈A 使得 ax} 严格大于 A 中某元素的元素集合‌下集‌ D(A){x∈P∣∃a∈A 使得 xa} 严格小于 A 中某元素的元素集合由于 A 是反链且不是全部极大元或极小元可以证明 U(A) 和 D(A) 都非空且 PA∪U(A)∪D(A)并且这三个集合两两不相交。现在我们考虑两个更小的偏序集P1​A∪D(A) 和 P2​A∪U(A)。它们的元素个数都严格小于 ∣P∣。在 P1​ 中A 仍然是它的最长反链因为 U(A) 中的元素都比 A 中某元素大不会和 A 形成更大的反链。根据归纳假设P1​ 可以被划分为 w 条链且由于 A 是反链这 w 条链的极大元恰好就是 A 中的 w 个元素。同理在 P2​ 中A 也是它的最长反链。根据归纳假设P2​ 也可以被划分为 w 条链且这 w 条链的极小元恰好就是 A 中的 w 个元素。现在我们把这两组链“对接”起来对于 A 中的每一个元素 ai​我们把 P1​ 中以 ai​ 为极大元的链和 P2​ 中以 ai​ 为极小元的链在 ai​ 处连接成一条新链。这样我们就得到了 w 条链它们完整地覆盖了整个 P。✅ 情况一得证。情况二对于每一条最长反链 A它要么全是极大元要么全是极小元这意味着最长反链 A 要么“漂浮”在 P 的最顶层要么“沉在”最底层。我们可以在 P 中选出一个极小元 x 和一个极大元 y并且满足 x≤y这样的 x,y 一定存在比如从 x 出发向上走一条链到某个极大元。从 P 中移除 x 和 y得到更小的偏序集 P′P∖{x,y}。关键点来了P′P′ 的最长反链长度一定是 w−1w−1。为什么因为 PP 的任何一条最长反链 AA长度为 ww根据我们的假设它要么全是极大元要么全是极小元。如果 AA 全是极大元那么它一定包含 yy移除 yy 后 AA 的长度减1如果 AA 全是极小元那么它一定包含 xx移除 xx 后 AA 的长度也减1。所以 P′P′ 中不可能再有长度为 ww 的反链。根据归纳假设P′P′ 可以被划分为 w−1w−1 条链。我们把 {x,y} 这条长度为2的链因为 x≤y加到刚才的划分中就得到了 PP 的一个链划分总共是 (w−1)1w 条链。✅ 情况二得证。最终结论综合第一步和第二步的证明我们得到最小链划分数 ≥w最小链划分数 ≤w因此两者必须相等。‌Dilworth定理得证‌对于任意有限偏序集其最小链划分数等于其最长反链的元素个数。例题除了经典的导弹拦截Dilworth定理在算法竞赛中还有很多巧妙的应用。它的核心思想就是把一个“最少划分”的问题转化为一个“最长序列”的求解问题往往能让看似复杂的题目豁然开朗。这里有几道典型的算法题正好可以帮你练练手加深理解。经典必刷导弹拦截系列这是Dilworth定理最直接的应用也是理解定理的绝佳起点。‌题目‌给定一个导弹高度序列一套系统每次拦截的高度不能高于前一次。求一套系统最多能拦截多少导弹最少需要多少套系统才能全部拦截‌定理应用‌‌第一问‌求‌最长不上升子序列‌的长度。‌第二问‌根据定理最少系统数等于序列中最长上升子序列的长度。因为每一枚在上升序列中的导弹都注定无法被同一套系统拦截必须“另起炉灶”。‌算法优化‌这题通常数据量不小用传统的动态规划O(n²)可能会超时。标准解法是用‌贪心二分查找‌将复杂度优化到O(n log n)。维护一个数组dd[i]表示长度为i的上升子序列的最小末尾元素通过二分查找来更新非常巧妙。思维进阶字符串染色问题这道题来自Codeforces是Dilworth定理更隐晦但有趣的应用。‌题目‌给一个字符串你可以给每个字符染色。规定只有相邻且颜色不同的字符才能交换位置。求最少需要多少种颜色使得经过若干次交换后字符串能按字典序从小到大排列并输出染色方案。‌定理应用‌‌转化问题‌题目允许交换最终要求有序。可以发现‌颜色相同的字符之间不能交换因此它们在原字符串中构成的子序列必须已经是非递减的‌。换句话说同一种颜色对应一个非递减子序列。‌核心结论‌问题就变成了最少需要多少种颜色才能将字符串划分成若干个非递减子序列根据Dilworth定理这个最小划分数就等于字符串中‌最长递减子序列‌的长度。‌构造方案‌每个字符的颜色编号可以直接等于以该字符结尾的最长递减子序列的长度。图论模型最小链覆盖与路径覆盖Dilworth定理在图论中也有重要地位常用来解决“覆盖”问题。‌最小链覆盖‌在一个有向无环图中用最少的、可以相交的路径覆盖所有点。这个问题可以通过‌Floyd传递闭包‌将“可以相交”转化为“不可相交”然后用‌二分图最大匹配‌来求解。而Dilworth定理则从另一个角度揭示这个最小链覆盖数等于图中最长反链的大小。‌例题‌比如给定一些任务及其先后依赖关系求最少需要多少条流水线才能完成所有任务就可以建模为最小链覆盖问题。更多应用场景Dilworth定理的应用远不止于此只要你能将问题建模为偏序集它就可能派上用场‌任务调度‌有一堆任务每个有开始和结束时间求最少需要多少台机器才能全部完成。如果任务间有偏序关系就可以用定理分析。‌嵌套问题‌比如俄罗斯套娃信封问题求最多能嵌套多少个以及最少能分成多少组互不嵌套的信封。‌序列划分‌任何将序列划分成若干个单调子序列的问题都可以考虑用Dilworth定理转化为求对偶单调子序列的长度。这些题目在洛谷、Codeforces、AcWing等在线评测平台上都能找到你可以搜索“导弹拦截”、“最小链覆盖”、“Dilworth定理”等关键词来练习。理解这个定理的精髓你会发现很多看似复杂的组合优化问题都能迎刃而解。