分治法的原理
分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。
有两点需要记住:
(1) 分治法基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。
(2)递归的解这些子问题,然后将各子问题的解合并得到原问题的解。
分治法的重点是分析问题是否可以划分为规模较小的子问题,难点是如何划分以及划分之后如何将各个子问题的解合并成最终的解。
这里照搬书籍:
算法分析
- 首先将X和Y分成A,B,C,D
- 此时将X和Y的乘积转化为(1)式,把问题转化为求解因式分解的值
在(1)式中,我们一共需要进行4次n/2的乘法(AC2次,AD、BC各一次)和3次加法,因而该算法的时间复杂度为:
通过master定理可以求得,跟小学算法的时间复杂度没有区别。
但是我们再来看看,我们是否可以用加法来换取乘法?因为多一个加法操作,也是常数项,对时间复杂度没有影响,如果减少一个乘法则不同。
(1)式化为:
(2)
现在的时间复杂度为:,通过master定理求得,。
代码:/* @大整数的乘法 */ #include <iostream> #include <algorithm> #include <cstring> #include <math.h> using namespace std; long long BigNumberMulity(int num1,int num2,int n){ if(num1 == 0 || num2 == 0){ return 0; }else if(n==1){ return num1 * num2; }else{ int A = num1/pow(10,(int)n/2); int B = num1-pow(10,(int)n/2)*A; int C = num2/pow(10,(int)n/2); int D = num2-pow(10,(int)n/2)*C; long long AC = BigNumberMulity(A,C,n/2); long long BD = BigNumberMulity(B,D,n/2); int E = BigNumberMulity(A-B,D-C,n/2)+AC+BD; return AC*pow(10,n)+E*pow(10,(int)n/2)+BD; } } int main(){ int x,y,n; while(true){ cin>>x>>y>>n; long long result1 = x*y; cout<<"普通法为:"<<result1<<endl; long long result2 = BigNumberMulity(x,y,n); cout<<"分治法为:"<<result2<<endl; } return 0; }