幂乘算法

问题:求 a n a^{n} an

分治算法设计思想

1.逐项相乘时需要做n-1次乘法运算,时间复杂度为 o ( n ) o(n) on
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} an1/2 * a ( n − 1 ) / 2 ∗ a a^{(n-1)/2} * a an1/2a,乘法的运算次数为(n-1)/2,同样减少。之后递归求解 a n / 2 a^{n/2} an/2 或者 a ( n − 1 ) / 2 a^{(n-1)/2} an1/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(n1))= ( 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;
}
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值