利用矩阵乘法可以将一个“向量”转换成另一个“向量”,若每一次转换的方式都是固定的话,那么就可以用多次乘一个中间矩阵A来达到将初始“向量”转换多次,相当于先求A的n次方,而求矩阵A的n次方可以用二分倍增来加速,这就是矩阵操作的意义所在,也就定义了矩阵快速幂这样一个操作的辅助作用。
和数据结构一样,矩阵也是“需要用时才用”,不能为了用矩阵而用矩阵,这偏离了解决问题的本质。
矩阵优化线性递推,根据初始状态以及递推式确立中间矩阵A,再通过快速幂求取第n项等。一些常见的中间矩阵的建法需要知道,比如说求矩阵和,等比矩阵和等。。。
矩阵优化状态递推,在有限的状态中可以通过某种方式进行转换成有限状态中的其他状态,比如状态压缩dp的状态转换,AC自动机的状态转换(还有待深入学习AC自动机),同样的在确定状态转换机制后建立中间矩阵A,通过快速幂获取n次转换后的状态
所以对于矩阵操作来说,最重要的最难的并不在于矩阵的操作,而是确定递推,不管是线性递推,还是状态递推等
矩阵乘法需要注意的一些东西:
1.一般矩阵乘法是O(n^3),可以通过在第三重循环前判断一个因子是否为0来避免第三重循环,这在做稀疏矩阵乘法时效率提升明显
2.循环矩阵,从第二行开始,每一行可以通过某种规则从上一行得出本行,则乘法的时候先O(n^2)求出第一行,在O(n^2)求出其他行,一般循环矩阵的题目都会卡这点的复杂度
3.若矩阵较大,则所有函数中不要定义矩阵,不要直接传递矩阵参数(用指针或引用),将所有用到的矩阵全定义成全集变量,不然会爆栈
4.一般涉及到矩阵操作都会求模,若矩阵中有负数,则一定要记着判断最后结果是否为负,题目要求正数结果则应+mod再%mod
目前做的一些题目:
poj 3233 Matrix Power Series(等比矩阵求和)
hdu 1588 Gauss Fibonacci(函数嵌套、转换、等比矩阵求和)
hdu 2256 Problem of Precision(矩阵快速幂,得出递推式有难度)
fzu 1683 纪念SlingShot (矩阵优化递推,递推矩阵求和)
poj 3735 Training little cats(关键是想到构建中间矩阵)
poj 1977 Odd Loving Bakers(矩阵)
poj 3420 Quad Tiling(状态压缩矩阵递推)
hdu 1757 A Simple Math Problem(矩阵优化递推)
hdu 2276 Kiki & Little Kiki 2(矩阵优化递推)
fzu 1692 Key problem(循环同构矩阵o(n^2)优化乘法)
la 3704 – Cellular Automaton(矩阵优化递推)