主定理是用来分析递归算法复杂度的高效工具。不深究原理,只应试,下面给出应试策略。

策略

主定理形如:

T(n)=aT(nb)+f(n)

主定理的核心是比较,到底递归到叶子结点的每个基本操作 (logba) 增长更快,还是减小问题规模 (f(n)) 的过程增长更快。

根据二者复杂度的强弱关系,分成三种情况:

  1. 基本操作增长(严格)更快, 则最终 T(n)Θ(nlogba);

  2. 降低规模增长(严格)更快, 则最终 T(n)Θ(f(n)), 但是需要满足一些条件, 否则进入情形 3;

  3. 二者速度相当, 则最终 T(n)Θ(nlogbalogε+1n), 注意有个 +1 的存在.

其中第 2 点不能一步来判别,还需要验证一个式子 af(nb)cf(n)(即递归调用的贡献足够小)

不过没关系,既然分成了三个 case,不妨用排除法,把剩下两种可能都排除掉,就只剩下第 2 种了。

例子

看几个例子。

维基百科

先是维基百科上的。

例 1 - 1

T(n)=T(n/2)+Θ(1)

注意到 logba=log21=0,所以基本操作是 O(1) 的复杂度。而 f(n) 也是 O(1)(不要被 Θ 吓到,O 是更弱的 Θ,只有上界)。

速度相当,取 ε=0 即可,s.t. f(n)Θ(nlogbalogεn)T(n)=Θ(logn)

例 1 - 2

T(n)=2T(n/2)+Θ(1)

注意到 logba=log22=1,所以基本操作是 O(n) 的复杂度。而 f(n)O(1)

基本操作更快,是情形 1,直接 T(n)=Θ(n)

例 1 - 3

T(n)=2T(n/2)+O(logn)

注意到 logba=log22=1,所以基本操作是 O(n) 的复杂度。而 f(n)O(logn)

基本操作快,是情形 1,直接 T(n)=Θ(n)

例 1 - 4

T(n)=2T(n/2)+Θ(n)

注意到 logba=log22=1,所以基本操作是 O(n) 的复杂度。而 f(n)O(n)

速度相当,f(n)Θ(n1log0n),则 T(n)=Θ(nlogn)

OI-WIKI

再看 OI-WIKI 的几个例子。

例 2 - 1

T(n)=T(n/2)+n

注意到 logba=log21=0,所以基本操作是 O(1) 的复杂度。而 f(n)O(n)

f(n) 更慢,要先排除情形 1。然后,情形三能满足吗?

f(n)Θ(n0logεn)?

没有这样的 ε,所以情形 3 不满足,只有可能是 2。

所以 T(n)=Θ(f(n))=Θ(n)

例 2 - 2

T(n)=T(n/2)+logn

注意到 logba=log21=0,所以基本操作是 O(1) 的复杂度。而 f(n)O(logn)

f(n) 更慢,要先排除情形 1。然后,情形三能满足吗?

f(n)Θ(n0logεn)?

可以的,ε=1 即可,所以 T(n)=Θ(log2n)

随堂小测

再看课堂上的随堂测试题。

例 3 - 1

T(n)=9T(n/3)+n

注意到 logba=log39=2,所以基本操作是 O(n2) 的复杂度。而 f(n)O(n)

基本操作慢,所以直接 T(n)=Θ(n2)

例 3 - 2

T(n)=T(2n/3)+1

注意到 logba=log1.51=0,所以基本操作是 O(1) 的复杂度。而 f(n)O(1)

速度相当,所以直接情形 3:T(n)=Θ(logn)

例 3 - 3

T(n)=3T(n/4)+nlogn

注意到 logba=log430.792,所以基本操作是 O(n0.792) 的复杂度。而 f(n)O(nlogn)

f(n) 更慢,要先排除情形 1。然后,情形 3 能满足吗?

f(n)Θ(n0.792logεn)?

不太行,所以情形 2,T(n)=Θ(nlogn)

例 3 - 4

T(n)=2T(n/2)+nlogn

注意到 logba=log22=1,所以基本操作是 O(n) 的复杂度。而 f(n)O(nlogn)

O(nlogn)O(n) 慢,也就是 f(n) 更慢,看看情形 3 满足吗?

f(n)Θ(n1logεn)?

可以的,ε=1 即可,所以 T(n)=Θ(nlog2n)

结语

总结了一些应试技巧,应该能覆盖所有的题目了,目前还没找到 bug。