1、
![](http://my.csdn.net/uploads/201206/29/1340955070_5653.png)
2、高斯发现两个复数乘法初看涉及4次实数乘法运算,但实际上可以简化为3次乘法运算。
例:(a+bi)(c+di) = ac - bd + (bc+ad)i ,其中bc+ad = (a+b)(c+d) - ac - bd
所以只需计算(a+b)(c+d) 、 ac 和 bd。
这条原理可以帮助我们实现更好的乘法运算,将n位的x、y分成n/2位长,于是:![](http://my.csdn.net/uploads/201206/29/1340955080_4204.png)
![](http://my.csdn.net/uploads/201206/29/1340955080_4204.png)
运行时间:T(n) = 3T(n/2) + O(n), 解得时间复杂度为n^1.59, 比n^2效率更高。
3、依据以下定理可迅速写出时间复杂度。
![](http://my.csdn.net/uploads/201206/29/1340955088_8654.png)
4、分治策略的典型应用:二分搜索和归并排序。
二分搜索:T(n) = T(n/2) + O(1) ==> O(logn)
归并排序:T(n) = 2T(n/2) + O(n) ==> O(nlogn)
归并排序代码(C++):
void mergeSort(int* a, int left, int right) { if(left == right) return; int mid = (left + right)/2; mergeSort(a,left,mid); mergeSort(a,mid+1,right); merge(a,left,mid+1,right); } void merge(int* a,int left, int mid, int right) { int *tmp = new int[right-left+1]; int i = left, j = mid, k = 0; while(i<mid && j <=right) { if(a[i] < a[j]) tmp[k++] = a[i++]; else tmp[k++] = a[j++]; } while(i<mid) tmp[k++] = a[i++]; while(j<=right) tmp[k++] = a[j++]; for(i = 0,k = left; k<=right;i++,k++) a[k] = tmp[i]; delete[] tmp; }
5、排序的下限:涉及两两比较的方法来对一组数进行排序的最优复杂度是O(nlogn),所以归并排序是最优排序。
当然也存在线性排序(O(n)),此法不涉及两两比较。例:对1,2,3,4,5,8,9,19,20排序,设一个bool型数组a[1..20],初值全为false,顺序扫一遍输入,扫到n,则把a[n]设为true,然后扫一遍a,把值为true的输出,即已排好序。但不适合对大数字排序。
6、寻找中位数的分治思想:在列表S中选取一个数v,然后将列表分为3个部分:比v小的数,比v大的数和等于v的数,分为设为SL,SR,SV,k代表寻找第k小的数,则:![](http://my.csdn.net/uploads/201206/29/1340955111_7511.png)
![](http://my.csdn.net/uploads/201206/29/1340955111_7511.png)
7、矩阵乘法:可以分解成7个n/2规模的子矩阵乘法,所以T(n) = 7T(n/2) + O(n^2), 解得O(n^2.81)