先扯两句
很多人说如果DP转移有循环节,直接矩乘就好了。但是像我这样这么蒟蒻的选手还是数不胜数的。
但是又有多少人真的懂矩乘?能够熟练掌握?
本人才疏学浅,以下观点只是我的一孔之见,希望大佬们批评指正。
矩阵乘法
这个东西其实不难。
大家都知道,矩阵 C = A B = A ∗ B C=AB=A*B C=AB=A∗B,其中矩阵 A A A, n n n行 p p p列,矩阵 B B B, p p p行 m m m列。则矩阵 C C C, n n n行 m m m列。
需要注意的地方:
只有A的列数=B的行数,才能够进行矩阵乘法。
原因:
矩阵乘法的公式: c [ i ] [ j ] = ∑ k = 1 p a [ i ] [ k ] ∗ b [ k ] [ j ] c[i][j]=\sum_{k=1}^p a[i][k]*b[k][j] c[i][j]=k=1∑pa[i][k]∗b[k][j]
在草稿纸上画一下:
在矩阵C的元素 ( i , j ) (i,j) (i,j),是矩阵A和B中对应元素的积(已用相同颜色标示)之和。
总共有p种颜色。能够进行矩阵乘法,当然需要A的列数等于B的行数。
DP转移矩阵最核心的地方
DP的转移如果存在循环节,且涉及的元素不多,则可以考虑用矩乘优化。
现在考虑 f [ i ] f[i] f[i]到 f [ i + 1 ] f[i+1] f[i+1]的转移。现在要解决两件事。①将 f [ i ] f[i] f[i]转移到 f [ i + 1 ] f[i+1] f[i+1],② f [ i ] f[i] f[i]的转移式中的其他项该如何更新。
通过矩阵乘法,能够解决上面的两件事。
方便地,现在要将 f [ n ] f[n] f[n]转移到 f [ n + 1 ] f[n+1] f[n+1]。