专栏文章

关于主定理的一个简洁的证明

算法·理论参与者 11已保存评论 10

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
10 条
当前快照
1 份
快照标识符
@miphcgzq
此快照首次捕获于
2025/12/03 12:01
3 个月前
此快照最后确认于
2025/12/03 12:01
3 个月前
查看原文

关于主定理的一个简洁的证明

upd on 2025.5.10 修改了一处笔误。

前言

上个赛季某次在 1121 训练时吐槽主定理难证,被翔哥听到骂了一顿,然后他给我讲了一种跟网上主流的证明方法非常不同的方法,仅用到高中学的简单的数列递推和归纳法,令我耳目一新,不过当时一带而过了,并没有记录下来。
直到今天的算法设计与分析课上重新提到了主定理,我再次从网上搜索证明,还是只能搜到那些长篇大论的推导,于是我重新回忆了一下翔哥教给我的推导方法,并打算开个博客记录一下。

定理

主定理适用于求解如下递归式算法的时间复杂度
T(n)=aT(nb)+O(nd)\begin{aligned} T(n) = aT(\frac{n}{b}) + O(n^d) \end{aligned}
结论为
T(n)={O(nd)        (bd>a)O(ndlogn)(bd=a)O(nlogba)(bd<a)\begin{aligned} T(n) = \left\{ \begin{aligned} &O(n^d) \ \ \ \ \ \ \ \ &(b^{d} > a) \\ &O(n^d\log n) &(b^{d} = a) \\ &O(n^{\log_{b}a}) &(b^{d} < a) \end{aligned} \right. \end{aligned}

证明

n=bkn = b^{k}(如果无法取整,则可以找到最小的 kk 使得 bk>nb^{k} > n,根据后续结论,这样做对时间复杂度只会产生常数级别的影响),则递归式可写为
T(bk)=aT(bk1)+O(bkd)\begin{aligned} T(b^{k}) = aT(b^{k - 1}) + O(b^{kd}) \end{aligned}
  • 先来分析 bd=ab^{d} = a 时的情况,此时递归式可写为
    T(bk)=aT(bk1)+O(ak)\begin{aligned} T(b^{k}) = aT(b^{k - 1}) + O(a^{k}) \end{aligned}
    将式子两边同时除以 aka^{k}​,可得
    T(bk)ak=T(bk1)ak1+O(1)\begin{aligned} \frac{T(b^{k})}{a^{k}} = \frac{T(b^{k - 1})}{a^{k - 1}} + O(1) \end{aligned}
    不难发现
    T(bk)ak=O(k)\frac{T(b^{k})}{a^{k}} = O(k)
    T(n)=T(bk)=O(akk)=O(bkdk)=O(ndlogn)\begin{aligned} T(n) = T(b^{k}) = O(a^{k}k) = O(b^{kd}k) = O(n^{d}\log n) \end{aligned}
  • bd>ab^{d} > a​ 时,考虑归纳法。
    显然,当 k=0k = 0 时,T(bk)=T(1)=O(1)=O(bkd)T(b^{k}) = T(1) = O(1) = O(b^{kd}) 成立。
    假设 T(bk)=O(bkd)T(b^{k}) = O(b^{kd})kKk \le K 时成立。
    考虑在 k=K+1k = K + 1 时,带入递归式得
    T(bK+1)=aT(bK)+O(b(K+1)d)=O(abKd+b(K+1)d)\begin{aligned} T(b^{K + 1}) = aT(b^{K}) + O(b^{(K + 1)d}) = O(ab^{Kd} + b^{(K + 1)d}) \end{aligned}
    由于 bd>ab^{d} > a,所以 abKd<bdbKd=b(K+1)dab^{Kd} < b^{d}b^{Kd} = b^{(K + 1)d},故
    T(bK+1)=aT(bK)+O(b(K+1)d)=O(b(K+1)d)\begin{aligned} T(b^{K + 1}) = aT(b^{K}) + O(b^{(K + 1)d}) = O(b^{(K + 1)d}) \end{aligned}
    T(bk)=O(bkd)T(b^{k}) = O(b^{kd})k=K+1k = K + 1 时也成立,故
    T(n)=T(bk)=O(bkd)=O(nd)T(n) = T(b^{k}) = O(b^{kd}) = O(n^{d})
  • bd<ab^{d} < a 时,同理,也考虑归纳法。
    显然,当 k=0k = 0 时,T(bk)=T(1)=O(1)=O(ak)T(b^{k}) = T(1) = O(1) = O(a^{k})​ 成立。
    假设 T(bk)=O(ak)T(b^{k}) = O(a^{k})kKk \le K 时成立。
    考虑在 k=K+1k = K + 1​ 时,带入递归式得
    T(bK+1)=aT(bK)+O(b(K+1)d)=O(aK+1+b(K+1)d)\begin{aligned} T(b^{K + 1}) = aT(b^{K}) + O(b^{(K + 1)d}) = O(a^{K + 1} + b^{(K + 1)d}) \end{aligned}
    由于 bd<ab^{d} < a,所以 aK+1>(bd)K+1=b(K+1)da^{K + 1} > (b^{d})^{K + 1} = b^{(K + 1)d},故
    T(bK+1)=aT(bK)+O(b(K+1)d)=O(aK+1)\begin{aligned} T(b^{K + 1}) = aT(b^{K}) + O(b^{(K + 1)d}) = O(a^{K + 1}) \end{aligned}
    T(bk)=O(ak)T(b^{k}) = O(a^{k})k=K+1k = K + 1​ 时也成立,故
    T(n)=T(ak)=O(bk(logba))=O(nlogba)T(n) = T(a^{k}) = O(b^{k(\log_{b}{a})}) = O(n^{\log_{b}a})

评论

10 条评论,欢迎与作者交流。

正在加载评论...