问题:求 a n a^{n} an
分治算法设计思想
1.逐项相乘时需要做n-1次乘法运算,时间复杂度为
o
(
n
)
o(n)
o(n)
2.当n为偶数时:
a
n
a^{n}
an=
a
n
/
2
a^{n/2}
an/2 *
a
n
/
2
a^{n/2}
an/2,
a
n
/
2
a^{n/2}
an/2可以只求一次,乘法的运算次数为n/2,运算次数减少。当n为奇数时,
a
n
a^{n}
an=
a
(
n
−
1
)
/
2
a^{(n-1)/2}
a(n−1)/2 *
a
(
n
−
1
)
/
2
∗
a
a^{(n-1)/2} * a
a(n−1)/2∗a,乘法的运算次数为(n-1)/2,同样减少。之后递归求解
a
n
/
2
a^{n/2}
an/2 或者
a
(
n
−
1
)
/
2
a^{(n-1)/2}
a(n−1)/2
3.时间复杂度分析,规模为n的问题可划分成规模不超过n/2的子问题,
w
(
n
)
=
w
(
n
/
2
)
+
Θ
(
1
)
w(n)=w(n/2)+\Theta(1)
w(n)=w(n/2)+Θ(1)求得
w
(
n
)
=
o
(
l
o
g
(
n
)
)
w(n)=o(log(n))
w(n)=o(log(n))
代码实现
#include <bits/stdc++.h>
using namespace std;
long long a_n(int a,int n){
long long result;
if(n==1){
result=(long long) a;
return result;
}
if(n%2==0){
result=a_n(a,n/2);
result=result*result;
}
else{
result=a_n(a,(n-1)/2);
result=result*result*a;
}
return result;
}
int main(){
int a=2,n=60;
int result=a_n(a,n);
return 0;
}
算法推广及应用:求矩阵的n次方
代码实现
void mul_matrix(long long a[RAW][COL],long long b[RAW][COL],long long c[RAW][COL]){
for(int i=0;i<RAW;++i){
for(int k=0;k<COL;++k){
c[i][k]=0;
for(int j=0;j<COL;++j){
c[i][k]+=a[i][j]*b[j][k];
}
}
}
}
void copy_matrix(long long a[][COL],long long b[][COL]){
for(int i=0;i<RAW;++i)
for(int j=0;j<COL;++j)
b[i][j]=a[i][j];
}
void matrix_n(long long a[][COL],long long c[][COL],int n){
if(n==2){
mul_matrix(a,a,c);
return;
}
if(n==1){
copy_matrix(a,c);
return;
}
if(n%2==0){
matrix_n(a,c,n/2);
long long copy_c[RAW][COL];
copy_matrix(c,copy_c);
mul_matrix(copy_c,copy_c,c);
return ;
}
else{
matrix_n(a,c,(n-1)/2);
long long copy_c[RAW][COL];
copy_matrix(c,copy_c);
mul_matrix(copy_c,copy_c,c);
copy_matrix(c,copy_c);
mul_matrix(copy_c,a,c);
}
}
应用:求斐波那契数列
斐波那契数列的性质:
(
f
(
n
+
1
)
f
(
n
)
f
(
n
)
f
(
n
−
1
)
)
\begin{pmatrix}f(n+1) & f(n)\\f(n) &f(n-1)\end{pmatrix}
(f(n+1)f(n)f(n)f(n−1))=
(
1
1
1
0
)
n
\begin{pmatrix}1 & 1\\1 &0\end{pmatrix} ^ {n}
(1110)n
可归纳证明该性质,再次不赘述,读者可自行百度。
代码实现
int main(){
long long a[2][2]={1,1,1,0};
long long c[2][2]={0,0,0,0};
int n=11;//斐波那契数列的第n项
matrix_n(a,c,n);
cout<<c[0][1];
return 0;
}