周六网易笔试的时候碰见了一道题,一开始想着去找规律,结果发现找不到很好的规律,后来发现可以化为矩阵乘法来做,同时利用矩阵的快速幂。
矩阵的快速幂其实是一个非常有用的算法,很多地方都有用到,比如斐波那契数列,还有周六网易笔试的那道编程题,还有图上的路径问题。现总结一下:
矩阵快速幂
矩阵的快速幂其实和一个数的快速幂是一样的,即将一个数的指数部分化成二进制表示的小数,然后依次求出在各个二进制位上该数的指数次方,然后再看在该二进制位上是否为1,如果为1则乘以res,如果为0则跳过。一个数的快速幂如下:
int pow(int a, int n) {
int res = 1;
while (n) {
if (n % 2)
res *= a;
a *= a;
n = n >> 1;
}
return res;
}
所以矩阵的快速幂如下【注意这里的矩阵是指的方阵,因为只有方阵才可以有指数次方】:
//矩阵乘法函数
vector<vector<int>> multi(const vector<vector<int>> &m,const vector<vector<int>> &n) {
int a = m.size(),b = m[0].size(),c = n[0].size();
vector<vector<int>> res(a, vector<int>(c, 0));
for (int i = 0; i < a; i++)
for (int j = 0; j < c; j++)
for (int k = 0; k < b; k++)
res[i][j] += m[i][k] * n[k][j];
return res;
}
//矩阵的快速幂
vector<vector<int>> q_pow(vector<vector<int>> m, int n) {
vector<vector<int>> res(m.size(), vector<int>(m.size(),0));
//初始化一个单位矩阵
for (int i = 0; i < m.size(); i++)
res[i][i] = 1;
while (n) {
if (n % 2)
res = multi(res, m);
m = multi(m, m);
n = n / 2;
}
return res;
}
矩阵的快速幂是一个 O(logN) 的算法 ,N表示幂数
有了矩阵快速幂这个基础知识后,我们来看哪些题目可以化为矩阵乘法和快速幂的。
斐波那契数列
关于斐波那契数列有三种求法:
动态规划
这种方法算法复杂度为 O(n)
#
矩阵快速幂
斐波那契的通项公式可以转化为如下的一个矩阵乘法形式