1、用途程序员
矩阵的一个重要的用途是进行递归是的计算,最明显的就是快速求数列的某一项的值。本文也是主要讲解这种算法的。算法
2、样例数组
这方面最简单的就是斐波那契问题了,这个相信是每一位程序员都熟知的,这里就不介绍了。ui
3、快速幂spa
既然是快速计算那确定是不能去一步一步慢慢求,这里咱们要用到二分的思想。求快速幂。在讲解矩阵中如何使用快速幂以前咱们先讲解一下如何在计算普通的幂的时候使用快速幂:code
好比咱们要计算2^100,按照普通的作法咱们是进行100次的乘法,固然是很慢的。这是咱们能够采用二分的思想,这是咱们就能够想要获得这个咱们能够是2^50*2^50,而后又能够分红四个2^25……这样一直继续下去最终在将时间复杂度下降到 O(log₂N)。首先介绍一种比较朴素的快速幂实现版本。线上一段代码:blog
1 long long quickpow(long long m,long long n,int k)//取余 2 { 3 long long b = 1; 4 while (n > 0) 5 { 6 if (n & 1) 7 b = (b*m)%k; 8 n = n >> 1 ; 9 m = (m*m)%k; 10 } 11 return b; 12 }
你们能够看到这段代码的思路很简单,就是二分的思想。代码虽少却大大加快了运算的速度。递归
4、矩阵快速幂class
矩阵快速幂的思路和通常整数是相同的,就像咱们会把矩阵的运算类比到数的运算,这里面的也是同样,你只须要重载一下运算,其余的就和上面的二分快速幂彻底同样了。在详细讲解以前咱们先看一段实际代码:效率
1 const int MAX = 3; 2 typedef struct 3 { 4 int m[MAX][MAX]; 5 }Matrix; 6 Matrix P={5,-7,4, 7 1,0,0, 8 0,1,0, 9 }; 10 Matrix I={1,0,0, 11 0,1,0, 12 0,0,1, 13 }; 14 Matrix matrixmul(Matrix a,Matrix b) //矩阵乘法 15 { 16 int i,j,k; 17 Matrix c; 18 for(i=0;i<MAX;i++) 19 for (j = 0; j < MAX;j++) 20 { 21 c.m[i][j] = 0; 22 for (k = 0; k < MAX; k++) 23 c.m[i][j] += (a.m[i][k] * b.m[k][j])%9997; 24 c.m[i][j] %= 9997; 25 } 26 return c; 27 } 28 Matrix quickpow(long long n) 29 { 30 Matrix m=P,b=I; 31 while(n>=1) 32 { 33 if(n&1) 34 b=matrixmul(b,m); 35 n=n>>1; 36 m=matrixmul(m,m); 37 } 38 return b; 39 }
从这段代码中咱们能够看出矩阵的快速幂与普通二分很类似,他们的不一样就是数字的运算换成了矩阵的运算,说的详细点就是说:
一、数字二分中的1换成了单位矩阵;
二、普通算数运算换成了矩阵运算。
其余部分还基本是相同的。
5、用矩阵解决斐波那契问题以及浅谈矩阵求解递归的推到
固然这个矩阵的快速幂不只运算很精巧,更加关键的是矩阵的用途很普遍(关于算法的Matrix67好像有篇列了十多种应用了,能够百度之。。。)这里我就斐波那契问题的矩阵解法为例简单介绍一下:
咱们知道斐波那契的递归表示为
f(n)=1 (n=0,n=1)
f(n)=f(n-1)+f(n-2) (n>=2)
通常的方法都是dp或者公式法求解,效率通常,若是咱们用矩阵求解就会发现速度的到了提高。那么究竟怎么把矩阵和一个递归式联系起来呢。这一点在网上也有一些资料。可是我我的以为若是不是要用高次矩阵的话,彻底不必去按那些晕晕的公式求解。掌握一点门路以后按配凑就能很快的出结论。
咱们的思路就是上面的第二个式子要可以在一个矩阵的乘式中体现出来,回忆一下矩阵乘法(弄图太麻烦了,直接扒了一张)
因而乎对照这看看咱们以为二位数组确定就能解决这个递归式了,尝试着咱们不难的到
到这就基本完了,余下的就是你要求那个就把后面的矩阵用快速幂连乘多少就行了,复杂度O(logn)(貌似是最快的方法求斐波那契了,直接村起来除外。。。),代码就省了。