矩阵

定义

\(m,n\) 是两个正整数,由数域 \(\mathbb{F}\)\(m\times n\) 个数 \(a_{i,j}\) 排成的一个 \(m\)\(n\) 列的矩形图表叫做矩阵 \(\mathbf{A}\)(或 \((a_{i,j})\)\((a_{i,j})_{m\times n}\)),表示为:

\[\begin{pmatrix}a_{1,1}&a_{1,2}&\cdots&a_{1,n}\\a_{2,1}&a_{2,2}&\cdots&a_{2,n}\\\vdots&\vdots&&\vdots\\a_{m,1}&a_{m,2}&\cdots&a_{m,n}\\\end{pmatrix} \]

称为 \(\mathbb{F}\) 上的一个 \(m\)\(n\) 列的矩阵或 \(m\times n\) 矩阵。特别地,当 \(m=n\) 时,称 \(m\times n\) 矩阵 \(\mathbf{A}\) 是一个 \(n\) 阶方阵。

\(M_{m,n}(\mathbb{F})=\{\mathbf{A}=(a_{i,j})_{m\times n}\mid a_{i,j}\in \mathbb{F}\}\) 为数域 \(\mathbb{F}\) 上的所有 \(m\times n\) 矩阵全体,\(M_n(\mathbb{F})=M_{n,n}(\mathbb{F})\) 为数域 \(\mathbb{F}\) 上的所有 \(n\) 阶方阵全体。

矩阵乘法

有两个矩阵 \(\mathbf{A}=(a_{i,j})_{m\times n},\mathbf{B}=(b_{i,j})_{n\times s}\),定义 \(\mathbf{A}\)\(\mathbf{B}\) 的乘积为矩阵 \(\mathbf{C}=(c_{i,j})\in M_{m,s}(\mathbb{F})\),其中:

\[c_{i,j}=\sum\limits_{k=1}^na_{i,k}b_{k,j} \]

即:\(\mathbf{C}\) 矩阵的第 \(i\) 行第 \(j\) 列的数,就是由矩阵 \(\mathbf{A}\)\(i\)\(n\) 个数与矩阵 \(\mathbf{B}\)\(j\)\(n\) 个数对应位置相乘再相加得到的。

矩阵乘法的性质

  1. 结合律

\[(\mathbf{A}\mathbf{B})\mathbf{C}=\mathbf{A}(\mathbf{B}\mathbf{C}) \]

证明:

\(\mathbf{A}=(a_{i,j})_{m\times n},\mathbf{B}=(b_{i,j})_{n\times s},\mathbf{C}=(c_{i,j})_{s\times t}\),对于 \(1\le i\le m,1\le j\le t\),比较 \((\mathbf{A}\mathbf{B})\mathbf{C}\)\(\mathbf{A}(\mathbf{B}\mathbf{C})\)\((i,j)\) 元素。

一方面,\(\mathbf{A}\mathbf{B}\) 的第 \(i\) 行元素为:

\[\left(\sum\limits_{k=1}^na_{i,k}b_{k,1},\sum\limits_{k=1}^na_{i,k}b_{k,2},\cdots ,\sum\limits_{k=1}^na_{i,k}b_{k,s}\right) \]

\((\mathbf{A}\mathbf{B})\mathbf{C}\)\((i,j)\) 元素为:

\[\sum\limits_{l=1}^s\left(\sum\limits_{k=1}^na_{i,k}b_{k,l}\right)c_{l,j}=\sum\limits_{l=1}^s\sum\limits_{k=1}^na_{i,k}b_{k,l}c_{l,j} \]

另一方面,\(\mathbf{B}\mathbf{C}\) 的第 \(j\) 列元素为:

\[\left(\sum\limits_{l=1}^sb_{1,l}c_{l,j},\sum\limits_{l=1}^sb_{2,l}c_{l,j},\cdots,\sum\limits_{l=1}^sb_{s,l}c_{l,j}\right)^T \]

\(\mathbf{A}(\mathbf{B}\mathbf{C})\)\((i,j)\) 元素为:

\[\sum\limits_{k=1}^na_{i,k}\left(\sum\limits_{l=1}^sb_{k,l}c_{l,j}\right)=\sum\limits_{l=1}^s\sum\limits_{k=1}^na_{i,k}b_{k,l}c_{l,j} \]

二者是相等的,于是结合律得证。

  1. 分配律

\[\mathbf{A}(\mathbf{B}+\mathbf{C})=\mathbf{A}\mathbf{B}+\mathbf{A}\mathbf{C} \]

证明:

与结合律类似,略。

注: 矩阵乘法不满足交换律与消去律。

矩阵快速幂与线性递推

利用矩阵乘法的结合律,我们可以使用快速幂的方法求一个矩阵 \(\mathbf{A}\)\(m\) 次幂 \(\mathbf{A}^m\),进而可以用于优化常系数齐次线性递推。

基础矩阵优化递推

已知一个数列 \(a\),它满足 \(a_n=\begin{cases}1&n\in\{1,2,3\}\\a_{n-1}+a_{n-3}&n\ge 4\end{cases}\),求 \(a\) 数列的第 \(n\) 项。

sol:

把转移写成矩阵形式:

\[\begin{bmatrix}1&0&1\\1&0&0\\0&1&0\end{bmatrix}\begin{bmatrix}a_{n-1}\\a_{n-2}\\a_{n-3}\end{bmatrix}=\begin{bmatrix}a_n\\a_{n-1}\\a_{n-2}\end{bmatrix} \]

矩阵快速幂求系数矩阵的 \(n-3\) 次幂即可,复杂度 \(O(\log n)\)

邻接矩阵的乘法

对一个有向图 \(G\),记其邻接矩阵为 \(A\),则 \(A^k\)\((i,j)\) 元素为从 \(i\) 出发,走 \(k\) 步走到 \(j\) 的路径数。

如果只考虑可达性,此时矩阵中只有 \(0\)\(1\),乘法变成与操作,加法变成或操作,使用 bitset 可以将矩阵乘法优化到 \(O(\frac{n^3}{\omega})\)

:除此之外,很多 dp 也可以用类似于常系数齐次线性递推的方式优化。

动态 dp

动态 dp,就是把状态转移方程改写为矩阵后用数据结构维护的算法。

这里的矩阵可以是常见的 \((+,\times)\) 矩阵,也可能是 \((\min/\max,+)\) 矩阵。

这里的 \((\max,+)\) 矩阵的矩阵乘法定义为:

矩阵 \(\mathbf{A}=(a_{i,j})_{m\times n},\mathbf{B}=(b_{i,j})_{n\times s}\),则 \(\mathbf{A}\mathbf{B}=(c_{i,j})_{m\times s}\),其中:

\[c_{i,j}=\max\limits_{1\le k\le m}\{a_{i,k}+b_{k,j}\} \]

这里的 \((\max,+)\) 矩阵乘法和 \((+,\times)\) 矩阵乘法一样,都具有结合律,即 \((\mathbf{A}\mathbf{B})\mathbf{C}=\mathbf{A}(\mathbf{B}\mathbf{C})\)

同样,在树形 dp 中,结合使用轻重链剖分等数据结构技巧,可以用动态 dp 的 \((\max,+)\) 矩阵快速维护树形 dp。

例题在后面。

例题

  1. 迷路

有向图有 \(n\) 个节点,节点从 \(1\)\(n\) 编号,边有边权。windy 从节点 \(1\) 出发,他必须恰好在 \(t\) 时刻到达节点 \(n\)

现在给出该有向图,你能告诉 windy 总共有多少种不同的路径吗?(\(2\le n\le 10\)\(1\le\) 边权 \(\le 9\)

sol:

拆边,若一条边 \(u\rightarrow v\) 的权值为 \(w\),那么新建点 \((x_1,x_2,\cdots,x_{w−1})\),连边 \(u\rightarrow x_1\rightarrow x_2\rightarrow\cdots\rightarrow x_{w−1}\rightarrow v\),边权均为 \(1\)

对新图的邻接矩阵求 \(t\) 次幂即可。

矩阵的大小是新图的点数 \(N=8m=8n^2\) 级别的,复杂度 \(O(N^3\log t)\)。但是复杂度还可以更优。

考虑对每个点拆点,\((u,0)\rightarrow(u,1)\rightarrow(u,2)\rightarrow \cdots\rightarrow(u,8)\)。对于一条 \(u\rightarrow v\),边权为 \(w\) 的边,连边 \((u,w-1)\rightarrow(v,0)\)

矩阵的大小是新图的点数 \(N=9n\) 级别的,复杂度 \(O(N^3\log t)\)

  1. 超级跳马

现有一个 \(n\)\(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角。

每一步它向右跳奇数列,且跳到本行或相邻行,且跳越期间,马不能离开棋盘。试求跳法种数。

数据范围:\(n\le50,m\le 10^9\)

sol:

\(f_{i,j}\) 表示跳到 \((i,j)\) 的方案数。

考虑从哪一行转移过来,有方程:

\[f_{i,j}=\sum\limits_{k=1}f_{i-1,j-(2k-1)}+f_{i,j-(2k-1)}+f_{i+1,j-(2k-1)} \]

发现 \(f_{i,j-2}=\sum\limits_{k=2}f_{i-1,j-(2k-1)}+f_{i,j-(2k-1)}+f_{i+1,j-(2k-1)}\),于是把方程转成线性递推的形式:

\[f_{i,j}=f_{i,j-2}+f_{i-1,j-1}+f_{i,j-1}+f_{i+1,j-1} \]

写成矩阵形式,以 \(n=3\) 为例:

\[\begin{bmatrix}1&1&0&1&0&0\\1&1&1&0&1&0\\0&1&1&0&0&1\\1&0&0&0&0&0\\0&1&0&0&0&0\\0&0&1&0&0&0\end{bmatrix}\begin{bmatrix}f_{1,j}\\f_{2,j}\\f_{3,j}\\f_{1,j-1}\\f_{2,j-1}\\f_{3,j-1}\end{bmatrix}=\begin{bmatrix}f_{1,j+1}\\f_{2,j+1}\\f_{3,j+1}\\f_{1,j}\\f_{2,j}\\f_{3,j}\end{bmatrix} \]

做矩阵快速幂即可,复杂度 \(O(n^3\log m)\)

  1. Placing Squares

给定一个长度为 \(n\) 的木板,木板上 \(n-1\) 个整数位置上有 \(m\) 个被标记。

现在你需要在木板上放置一些不相交正方形,正方形需要满足:边长为整数、底面需要紧贴木板、正方形不能超出木板、正方形要将所有的木板覆盖、标记点的位置不能是两个正方形的交界处。

一种合法的正方形放置方案的贡献为所有正方形面积之积,求出所有合法方案的贡献之和。

sol:

先不考虑有标记的情况。那么这个问题有一个巧妙的转化:

  • 一排 \(n\) 个格子,需要用板子把他们分成若干段。

  • 每段的格子里放有恰好两个不同颜色小球,方案数 \(a^2\)

这个问题的方案数就是所有正方形面积之积的和。

考虑 dp,设 \(f_{i,j}\) 表示前 \(i\) 个格子里,最后一段没有被封口的格子里有 \(j\in[0,2]\) 个小球的方案数,有转移:

  • \(f_{i+1,0}=f_{i,0}+f_{i,2}\)(在 \(i\)\(i+1\) 之间放隔板或不放隔板)。

  • \(f_{i+1,1}=2f_{i,0}+f_{i,1}+2f_{i,2}\)(放隔板可以从 \(f_{i,2}\) 转移过来,由于有两种颜色的球所以乘 \(2\);不放隔板可以从 \(f_{i,0},f_{i,1}\) 转移过来,同理 \(f_{i,0}\) 前的系数也需乘 \(2\))。

  • \(f_{i+1,2}=f_{i,0}+f_{i,1}+2f_{i,2}\)(放隔板可以从 \(f_{i,2}\) 转移过来,不放隔板可以从 \(f_{i,0},f_{i,1},f_{i,2}\) 转移过来;以上四种情况均只有一种放法,而 \(f_{i,2}\) 前系数的 \(2\) 是因为 \(f_{i,2}\) 出现了两次)。

于是可以写出矩阵形式:

\[\begin{bmatrix}1&0&1\\2&1&2\\1&1&2\end{bmatrix}\begin{bmatrix}f_{i,0}\\f_{i,1}\\f_{i,2}\end{bmatrix}=\begin{bmatrix}f_{i+1,0}\\f_{i+1,1}\\f_{i+1,2}\end{bmatrix} \]

现在考虑有标记的情况:按标记分段,每段中间矩阵快速幂,然后遇到标记特判一下转移。

特殊的转移:

  • \(f_{i+1,0}=f_{i,0}\)

  • \(f_{i+1,1}=2f_{i,0}+f_{i,1}\)

  • \(f_{i+1,2}=f_{i,0}+f_{i,1}+f_{i,2}\)

矩阵形式:

\[\begin{bmatrix}1&0&0\\2&1&0\\1&1&1\end{bmatrix}\begin{bmatrix}f_{i,0}\\f_{i,1}\\f_{i,2}\end{bmatrix}=\begin{bmatrix}f_{i+1,0}\\f_{i+1,1}\\f_{i+1,2}\end{bmatrix} \]

于是解决了问题,复杂度 \(O(m\log n)\)

  1. New Year and Old Subsequence

定义一个数字串是好的当且仅当:该串包含子序列 2017,且不包含子序列 2016

给定长为 \(n\) 的数字串 \(t\)\(q\) 次询问,每次询问给出 \(l,r\),求把 \(t[l,r]\) 这个子串变成好的,最少要删除几个字符。

sol:

先考虑一个串怎么做,直接 dp:

\(f_{i,0/1/2/3/4}\) 表示 \(i\) 个数字的子序列中出现 \(\varnothing\)/2/20/201/2017 且不出现 2016 最少需要删去多少个字符,有转移:

  • \(f_{i,0}=f_{i-1,0}+[s_i=2]\)

  • \(f_{i,1}=\min(f_{i-1,1}+[s_i=0],f_{i-1,0}[s_i=2])\)

  • \(f_{i,2}=\min(f_{i-1,2}+[s_i=1],f_{i-1,1}[s_i=0])\)

  • \(f_{i,3}=\min(f_{i-1,3}+[s_i=7\lor s_i=6],f_{i-1,2}[s_i=1])\)

  • \(f_{i,4}=\min(f_{i-1,4}+[s_i=6],f_{i-1,3}[s_i=7])\)

把它写成 \((\min,+)\) 矩阵,用线段树维护区间矩阵之积即可。

复杂度 \(O(q\log n)\)

posted @ 2025-02-13 16:21  O_v_O  阅读(33)  评论(0)    收藏  举报