学习笔记:矩阵

今天讲了矩阵……就总结一下好了

http://blog.csdn.net/tomorrowtodie/article/details/52311373

http://www.matrix67.com/blog/archives/276 矩阵经典例题

很多内容来自学姐课件

矩阵

啥是矩阵?这个很好懂吧?

(不懂我也没办法)

大体就长这样

矩阵乘法

蛤?两个矩阵怎么做乘法?并不是所有矩阵都能做乘法的。

只有n行p列的矩阵和p行m列的矩阵才可以相乘。

相乘完就是一个n*m的矩阵喽。

就这样子。左边的每一行分别去和右边的每一列相乘,然后取和

比如取了左边的第二行和右边的第一列相乘

那么他们的和就应该放在结果的第二行第一列上。

代码如下:

1 for (int i=1;i<=n;++i)
2     for (int j=1;j<=m;++j)
3         for (int k=1;k<=p;++k)
4             c[i][j]+=a[i][k]*b[k][j];

代码是不是看起来很水?理解了就很好懂了……

WARNING!

矩阵乘法不满足交换律!即A*B!=B*A

但矩阵乘法满足结合律!即A*B*C=A*(B*C)

矩阵乘法的应用

恩……说了这么多矩阵乘法究竟该怎么用呢?

FIRST 矩阵乘法优化DP

这可能是矩阵乘法用的最多的地方了吧……

举个栗子

求Fibonacci数列第n项的值

n<=1018

数据这么大要是一步步安稳递推我们怕不是要TLE到飞起

那就走个捷径好了

快速幂!

……

哎等等不是应该用矩阵乘法吗

如图

哎这样是不是就能做了?

先给上式中第二个矩阵命名为P,给矩阵[F[2],F[1]]命名为A

那么[F[3],F[2]]就可以用矩阵A*P计算得出。同理

若求F[10]就可以A*P8,而P8我们就可以用快速幂求了

复杂度为log级别。模板如下:

 1 struct Mar
 2 {
 3     int a[N][N];
 4 } unit, A,ans;
 5 //PS这里的unit为单位矩阵,即左上角到右下角对角线为1的矩阵,它有一个性质,即为任何矩阵乘上单位矩阵都为本身
 6 Mar Mul(Mar a, Mar b)//矩阵乘法
 7 {
 8     Mar ans;
 9     memset(ans.a,0,sizeof(ans.a));
10     for (int k=1; k<=n; ++k)
11         for (int i=1; i<=n; ++i)
12             for (int j=1; j<=n; ++j)
13                 ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%Mod;
14     return ans;
15 }
16 Mar Qpow(Mar a,int p)//矩阵快速幂
17 {
18     Mar ans=unit;//相当于快速幂中的初始化为1
19     while (p!=0)
20     {
21         if (p&1)
22             ans=Mul(ans,a);
23         a=Mul(a,a);
24         p>>=1;
25     }
26     return ans;
27 }

练习

已知递推式F(n)=2*F(n-1)+3*F(n-2),求F(n)

已知递推式F(n)=F(n-1)+3*F(n-2)+4*F(n-4),求F(n)

已知递推式F(n)=sigma(i=1..10)a[i]*F(n-i),读入a[i]数组,求F(n)

BZOJ1898 沼泽鳄鱼

(核心:12为一个周期)

 

SECOND 图的邻接矩阵+矩阵乘法

????

这是个啥玩意儿?

构造无向图的邻接矩阵G

G*G以后得到一个什么东西? (GG)

可发现

如果(i,j)=1并且(j,k)=1

那么G*G(i,k)+=1

经过了两条边!

G^k 即为经过了k条边

可以扩展到有向图

若想要可以在一个点停留

如果不允许走回头路呢?

对于一个无向图,我们可以将边变为点,若从能点a经过边i到b,再从点b经过边j到c,那么就化边为点,设i,j两边可以相互抵达,用邻接矩阵存即可,类似上面的不能在一个点停留。

例:BZOJ1875 HH去散步

矩乘DP的特点?

一般看到那种某个限制的范围非常小的就可以考虑一下矩乘

但是也有可能是状压

如果一个限制非常小,一个限制非常大,那基本上就是矩乘了

long long 太慢了!

少取模!

原文地址:https://www.cnblogs.com/refun/p/8686086.html

时间: 2024-10-11 11:11:55

学习笔记:矩阵的相关文章

学习笔记——矩阵(1) 02.15

在这种作业极少的美好夜晚里 听着轻音乐看看书学学东西再和心爱的姑娘说上几句 真是再美好不过了 由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵.记作: 这m×n 个数称为矩阵A的元素,简称为元,数aij位于矩阵A的第i行第j列,称为矩阵A的(i,j)元,以数 aij为(i,j)元的矩阵可记为(aij)或(aij)m × n,m×n矩阵A也记作Amn. 加法 矩阵的加法满足下列运算律(A,B,C都是同型矩阵): 应该注意的是只有同型矩阵之间才可以进行加法 减法

学习笔记::矩阵树定理

我很懒惰,没有理解 是这样做的 先计算每个点的度数 a[i][j]=i到j边数*-1 进行高斯消元 最后把对角线乘起来就是答案 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define eps 1e-9 #define N 20 int n,m; int d[N][N],c[N][N]; double a[N][N];

JAVA学习笔记-矩阵相加

package MyDuoWeiShuZu; public class Mycode { public static void show(int[][] c){ for(int j=0;j<c.length;j++){ for(int i=0;i<c.length;i++){ System.out.print(c[j][i]+"\t"); } System.out.println(); } } public static int[][] add(int[][] a,int[

算法学习笔记 递归之 快速幂、斐波那契矩阵加速

递归的定义 原文地址为:http://blog.csdn.net/thisinnocence 递归和迭代是编程中最为常用的基本技巧,而且递归常常比迭代更为简洁和强大.它的定义就是:直接或间接调用自身.经典问题有:幂运算.阶乘.组合数.斐波那契数列.汉诺塔等.其算法思想: 原问题可分解子问题(必要条件): 原与分解后的子问题相似(递归方程): 分解次数有限(子问题有穷): 最终问题可直接解决(递归边界): 对于递归的应用与优化,直接递归时要预估时空复杂度,以免出现用时过长或者栈溢出.优化递归就是以

《学习opencv》笔记——矩阵和图像操作——cvGEMM,cvGetCol,cvGetCols and cvGetDiag

矩阵和图像的操作 (1)cvGEMM函数 其结构 double cvGEMM(//矩阵的广义乘法运算 const CvArr* src1,//乘数矩阵 const CvArr* src2,//乘数矩阵 double alpha,//1号矩阵系数 const CvArr* src3,//加权矩阵 double beta,//2号矩阵系数 CvArr* dst,//结果矩阵 int tABC = 0//变换标记 ); tABC变换标记及其对应的含义 CV_GEMM_A_T 转置 src1 CV_GE

《学习opencv》笔记——矩阵和图像操作——cvDet,cvDit,cvDotProduct,cvEigenVV and cvFlip

矩阵和图像的操作 (1)cvDet函数 其结构 double cvDet(//计算矩阵的行列式 const CvArr* mat ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <iostream> using namespace std; int main() { double va[] = {1,0,0,0,2,0,0,0,3}; CvMat Va=cvMa

《学习opencv》笔记——矩阵和图像操作——cvSetIdentity,cvSolve,cvSplit,cvSub,cvSubS and cvSubRS

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

《学习opencv》笔记——矩阵和图像操作——cvAdd、cvAddS and cvAddWeighted

矩阵和图像的操作 (1)cvAdd函数 其结构 void cvAdd(//图像加和 const CvArr* src1,//第一个原矩阵 const CvArr* src2,//第二个原矩阵 CvArr* dst, //存放矩阵 const CvArr* mask = NULL: //控制点 ); 就是单纯的将两个图像加和,mask变量控制加和的元素点,相当于"开关的作用"; 程序实例 #include <cv.h> #include <highgui.h> #

《学习opencv》笔记——矩阵和图像操作——cvCrossProduct and cvCvtColor

矩阵和图像的操作 (1)cvCrossProduct函数 其结构 void cvCrossProdust(//计算两个三维向量的叉积 const CvArr* src1, const CvArr* src2, CvArr* dst ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <iostream> using namespace std; int main()

《学习opencv》笔记——矩阵和图像操作——cvCalcCovarMatrix,cvCmp and cvCmpS

矩阵和图像的操作 (1)cvCalcCovarMatrix函数 其结构 void cvCalcCovarMatrix(计算给定点的均值和协方差矩阵 const CvArr** vects,//给定向量 int count,//给定向量的组数 CvArr* cov_mat,//结果矩阵 CvArr* avg,//根据flag得到结果 int flags//标记位 ); 标记位参数值极其意义 标志参数的具体标志值 意义 CV_COVAR_NORMAL 计算均值和协方差 CV_COVAR__SCRAM