我是靠谱客的博主 畅快苗条,最近开发中收集的这篇文章主要介绍矩阵快速幂简介,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

引入
思考一个问题:求斐波那契数列的第10^18对1e9+7取余的结果。
首先,如果按暴力递推的方法必定超时,那么现在就要引入一个新的算法了:矩阵快速幂,时间复杂度为log(n),这样就可以轻松的解决这个问题了。
算法前提
这里就不多介绍这两个算法的原理了,可课下自行查找
直接上代码:
1、整数快速幂。
快速求出a的k次方然后对p取余的结果

typedef long long ll;
int pmi(ll a,ll k,ll p){
    ll res=1;
    while(k){
    if(k&1) res=res*a%p;
    a=a*a%p;
    k>>=1;
    }
    return res;
}

2、矩阵乘法。
求矩阵A乘以矩阵B的结果(结果矩阵中的所有数都对mod取余)

Node mu(Node A,Node B,int mod) {
    Node ans;
    ans.init();
    for(int i=1; i<7; i++) {
        for(int j=1; j<7; j++) {
            for(int k=1; k<7; k++)
                ans.a[i][j]=(ans.a[i][j]%mod+A.a[i][k]%mod*B.a[k][j]%mod)%mod;
        }
    }
    return ans;
}

算法原理
斐波那契数列的地推式为:f[1]=f[2]=1 (n<=2) , f[n]=f[n-1]+f[n-2] (n>2);
那么这里只讨论n>2的情况就够了
不难发现 :
f[n+1]=f[n]+f[n-1]
f[n]=f[n-1]+f[n-2]
这连个矩阵是有联系的,这不是废话吗
现在可以设矩阵A是a[1][2] = { f[n-1], f[n-2] },矩阵B是b[2][2]={ {1, 1}, {1, 0} },这里就可以发现了:矩阵A乘以矩阵B就等于{ f[n], f[n-1] },那么这样就可以直接去第一个元素就是f[n]了。
我们可以继续从矩阵a[1][2] = { f[n-1], f[n-2] }往下推,不难发现:矩阵a[1][2]={ 1, 1 }乘以b[2][2]={ {1, 1}, {1, 0} }的n-2次方就等于矩阵{ f[n], f[n-1] }
这样就有了矩阵快速幂的算法。
那么问题来了:我们该如何构造矩阵A和B呢?
一般情况下 我们会得到一个递推式 例如f[n]=f[n-1]+f[n-2]+1,f[1]=f[2]=1;
因为f[n]=f[n-1]+f[n-2]+1,这样我们就要把A矩阵设为A={ f[2], f[1], 1},因为我们最终要到的矩阵为{ f[n], f[n-1], 1 },我们就要看他的前一项是多少,显然,他的前一项是{ f[n-1], f[n-2], 1 },我们要构建一个矩阵与{ f[n-1], f[n-2], 1 }可以得到{ f[n], f[n-1], 1 },显然这个矩阵大小是33的
通过思考我们不难发现这个B矩阵就是
0 1 0
1 1 0
0 1 1
所以就得到了A
B^(n-2)={ f[n], f[n-1], 1 };
这样的构造方法是要靠多练习的
今日份快乐传送门

最后

以上就是畅快苗条为你收集整理的矩阵快速幂简介的全部内容,希望文章能够帮你解决矩阵快速幂简介所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部