分治法
乘方问题
输入一个实数x,一个整数n >= 0,计算xn。
朴素算法即时对n个x连乘。
分治法:
xn = xn/2 · xn/2 如果n为偶数
xn = x(n-1)/2 · x(n+1)/2 如果n为奇数
T(n) = T(n/2) + θ(1) = θ(lg n)
#include<stdio.h> double Power_Divide(double x, int n); int main() { int n; double x; scanf("%d%lf", &n, &x); printf("%.3f", Power_Divide(x, n)); return 0; } double Power_Divide(double x, int n) { if(n == 1) return x; else if(n % 2 == 0) return Power_Divide(x, n / 2) * Power_Divide(x, n / 2); else if(n % 2 != 0) return Power_Divide(x, (n + 1) / 2) * Power_Divide(x, (n - 1) / 2); }
Bottom-up algorithm
自下而上递归解决的算法
在理论上,根据斐波那契数列的性质
可采用朴素平方递归式求第n项的斐波那契数列
Fn = Φn / √5 并取整至最接近的整数。可以用平方递归在 log n 的时间内计算出。
但是在现实的计算中无法实现。
根据斐波那契数列的一个定理:
通过计算矩阵的n次幂来得到Fn。
这时候是一个log n 的时间算法。
#include<stdio.h> #include<stdlib.h> int **Matrix(int **a1, int **a2); int **Power_Divide(int **a, int n); int main() { int **a = (int **)malloc(2 * sizeof(int *)), **a2; int n; scanf("%d", &n); for(int i = 0; i < 2; i++) a[i] = (int *)malloc(2 * sizeof(int)); a[0][0] = 1;a[0][1] = 1;a[1][0] = 1;a[1][1] = 0; a2 = Power_Divide(a, n); printf("Fn = %d ",a2[0][1]); } int **Matrix(int **a1, int **a2) { int **result; result = (int **)malloc(2 * sizeof(int *)); for(int i = 0; i < 2; i++) result[i] = (int *)malloc(2 * sizeof(int)); result[0][0] = a1[0][0] * a2[0][0] + a1[0][1] * a2[1][0]; result[0][1] = a1[0][0] * a2[0][1] + a1[0][1] * a2[1][1]; result[1][0] = a1[1][0] * a2[0][0] + a1[1][1] * a2[1][0]; result[1][1] = a1[1][0] * a2[0][1] + a1[0][1] * a2[1][1]; return result; } int **Power_Divide(int **a, int n) { if(n == 1) return a; else if(n % 2 == 0) return Matrix(Power_Divide(a, n / 2), Power_Divide(a, n / 2)); else if(n % 2 != 0) return Matrix(Power_Divide(a, (n + 1) / 2), Power_Divide(a, (n - 1) / 2)); }
矩阵的乘法问题
Input: 两个 n × n 的矩阵
Output: 矩阵乘法的结果
设A和B是两个n × n的矩阵,其中n可以写成2的幂。将A和B分别等分成4个小矩阵,此时如果把A和B都当成2×2矩阵来看,每个元素
就是一个(n /2) × (n /2) 矩阵,而A 和 B乘积就可以写成
常规的分块矩阵乘法计算
这时需要8次矩阵乘法,四次矩阵加法,则所需时间T(n) = 8T(n / 2) + Θ(n2) = Θ(n3)(用主定理可以得出)
这与常规的矩阵乘法算法一样复杂。
可利用斯特拉森算法得到7个小矩阵,分别定义为:
矩阵M1~M7可以通过7次矩阵乘法、6次矩阵加法和4次矩阵减法计算得出,C1~C4可以用矩阵M1~M7
通过6次矩阵加法和2次矩阵减法得出,方法如下:
即可得到T(n) = 7 T(n / 2) + Θ(n2) = Θ(nlg 7) = O(n2.81)