本章通过两个例子介绍分治策略,然后介绍三种方法求解递归式。
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
left_sum = - MAX
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left_sum
left_sum = sum
max_left = i
right_sum = - MAX
sum = 0
for j = mid + 1 to high
sum = sum + A[j]
if sum > right_sum
right_sum = sum
max_right = j
return(max_left, max_right, left_sum + right_sum)
FIND-MAXIMUN-SUBARRAY(A, low, high)
if high == low
return(low, high, A[low])
else
mid = (low + high) / 2
(left_low, left_high, left_sum) = FIND-MAXIMUN-SUBARRAY(A, low, mid)
(rihgt_low, rihgt_high, rihgt_sum) = FIND-MAXIMUN-SUBARRAY(A, mid + 1, high)
(cross_low, cross_high, cross_sum) = FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
if left_sum >= right_sum and left_sum >= cross_sum
return(left_low, left_high, left_sum)
elseif right_sum >= left_sum and right_sum >= cross_sum
return(right_low, right_high, right_sum)
else
return(cross_low, cross_high, cross_sum)
这里因为展现分治策略所以这样做,但复杂度略高, T(n)=Θ(nlgn) 。
这里给出一个我认为比较简单的方法,其本质是动态规划。
FIND-MAXIMUN-SUBARRAY(A, low, high)
now_sum = -MAX
max_sum = -MAX
left = low
right = low
for i = low to high
if now_sum < 0
now_sum = 0
left = i
now_sum +=A[i]
if now_sum > max_sum
max_sum = now_sum
right = i
return(left, right, max_sum)
普通方法: T(n)=Θ(n3)
SQUARE-MATRIX-MULTIPLY(A, B)
n = A.row
let C be a new nxn matrix
for i = 1 to n
for j = 1 to n
C[ij] = 0
for k = 1 to n
C[ij] += A[ik] * B[kj]
Strassen方法: T(n)=Θ(nlg7)
1. 将A、B和C分解成 n2×n2 的子矩阵
2. 创建10个 n2×n2 的矩阵 S1,S2,...,S10 ,每个矩阵保存步骤1中创建的两个子矩阵的和或差
3. 用步骤1中创建的子矩阵和步骤2中创建的10个矩阵,递归地计算7个矩阵积 P1,P2,...,P7
4. 通过 Pi 矩阵的不同组合进行加减运算,计算出结果矩阵C的子矩阵 C11,C12,C21,C22
步骤2中,创建如下10个矩阵:
步骤3中,递归地计算7次矩阵乘法:
注:反正我记不住这些矩阵计算,也不想记,Strassen方法不怎么实用=。=
到目前为止,nxn矩阵相乘的渐进复杂度最优的算法是Coppersmith和Winograd提出的,运行时间为 O(n2.376) ,已经很好了,毕竟下界是 Ω(n2) 。
步骤:
在2.2节中就用到过递归树,可参考2.2那节内容。
递归树主要是计算每层的代价和递归树的层数。
定理4.1(主定理):令 a≥1 和 b>1 是常数, f(n) 是一个函数, T(n) 是定义在非负整数上的递归式:
注:这里的小于大于都是指多项式意义上的小于大于,如果函数 f(n) 落在间隙中,不能用主方法来求解递归式。