[Algorithm]分治法 Divide and Conquer 与 主定理 Master Theorem

警:此文是理论深度文,如果想从这里找源代码或者“神马是归并排序”之类的东西的话,提前放弃吧。这文的来源主要是MIT的算法导论。

主定理 Master Theorem

这中文名字十分蛋疼(其实英文名字也十分蛋疼),我感觉确切地应该叫做递归复杂度判定定理,不过姑且就这么用吧。

分治法 Divide and Conquer

分治法分为三步:分、治、合(Divide, Conquer, Combine)。

分是递归的,不是说分一次就结束了,分后的子问题,被看做一个完整的问题,再进行分的过程,否则,算法的复杂度是不会降低的。

分治法的时间复杂度计算

使用公式:

然后套用主定理求解,PS:不适用主定理时,就悲剧鸟~

分治法举例

归并排序 Merge Sort

too simple, something naive了,简单说下就是:分成子队列、子队列排序、合并子队列。这一过程迭代执行

公式:

套用主定理第2种情况,得

二分查找

更加simple:先和队列中点比较,选择结果的位置,然后再从子队列中查找。这一过程迭代执行。队列必须是有序的。

公式:

套用主定理第1种情况,得

求幂值ax

分治法不是唯一的方法,这和前边两个不大一样,确切说小标题应该是“用分治法求幂值”

简单说是先求ax/2,然后再求ax/2*ax/2得出结果,当然,这一步骤也是要递归的。

公式:

套用主定理第1种情况,得

矩阵乘法

正常的算法,套用公式

使用i、j、k三重循环,复杂度为n3

使用分治法,将矩阵分块,进行分块相乘(主方法第一种情况):

是不能降低复杂度的,悲了个摧。

Strassen's Algorithm

http://en.wikipedia.org/wiki/Strassen_algorithm

应用这个算法,可以将复杂度降低一点点……

时间复杂度是

求斐波那契数值 Fibonacci Numbers

多说一句,如果用递归求斐波那契,则

斐波那契无法直接使用分治法求解,不过其计算公式可以使用分治法求值。

这是错误的方法:

斐波那契近似计算公式

其中的幂值计算可以使用分治法,最终复杂度为

不过计算机无法精确计算浮点数,也就是说会存在误差累积的问题~(另外据说大数乘法也不是常数时间,据说而已)

所以不可行。

这是正确的方法,使用了线性代数:

斐波那契计算公式

硬件布线

分治法还可以有神奇的用途,例如计算硬件布线占用的电路板面积:

方案1下的:

目标方案的:

可以反推出

如果有灵感的话,可以得出H布局

原文地址:https://www.cnblogs.com/SelaSelah/p/2535271.html