矩阵优化dp

news/2026/1/22 7:35:24/文章来源:https://www.cnblogs.com/fnoihzhyan/p/19514859

矩阵乘法

考虑一个 \(n\times m\)(即 n 行 m 列)的矩阵乘上一个 \(m\times k\) 的矩阵,乘法后得到 \(n\times k\) 的矩阵。

代数的写法就是

\[C_{i,j}=\sum_{t=1}^m A_{it}\cdot B_{tj} \]

在写的时候,先枚举 \(i,k\),如果 \(A_{ik}\)\(0\) 的话就直接跳过这一维能够部分优化常数。

\(C_{i,j}\) 由矩阵 \(A\) 的第 \(i\) 行和矩阵 \(B\) 的第 \(j\) 列的乘积和构成,注意不要搞混了

注意到矩阵只有结合律而没有交换律

所以 \(A,B,C\) 是三个矩阵,那么 \(ABC\) 可以是 \(A(BC)\) 但不能是 \(BCA\)

矩阵快速幂优化计算

把矩阵看作一个数,用对于数做快速幂的方法对于矩阵做快速幂,就是矩阵快速幂了,实现上通常会定义一个矩阵类/结构体,封装一个矩阵乘法。

这样就能快速地求出一个矩阵的 \(n\) 次方了。

矩阵快速幂只适用于方阵,即 \(n\times n\) 的矩阵,并且约定 \(A^0=I\)\(I\) 为单位矩阵。

P1939

这道题目,要求求出一个数列的第 \(x\) 项,且 \(x\) 很大。

\[a_x= \begin{cases} 1&x\in\{1,2,3\}\\ a_{x-1}+a_{x-3}&x\geq 4 \end{cases} \]

那么我们考虑使用一个矩阵 \(\begin{bmatrix}a_x\\a_{x-1}\\a_{x-2}\end{bmatrix}\) 来描述一个状态。

发现状态间有

\[\begin{bmatrix} a_x\\ a_{x-1}\\ a_{x-2} \end{bmatrix} = \begin{bmatrix} 1&0&1\\ 1&0&0\\ 0&1&0\\ \end{bmatrix} \cdot \begin{bmatrix} a_{x-1}\\ a_{x-2}\\ a_{x-3}\\ \end{bmatrix} \]

可以依照下图理解一下,对应行和对应列的相同颜色的项相乘,然后和就是红色的那个值了。

\[\begin{bmatrix} \color{red}{a_x}\\ a_{x-1}\\ a_{x-2} \end{bmatrix} = \begin{bmatrix} \color{blue}1&\color{green}0&\color{orange}1\\ 1&0&0\\ 0&1&0\\ \end{bmatrix} \cdot \begin{bmatrix} \color{blue}a_{x-1}\\ \color{green}a_{x-2}\\ \color{orange}a_{x-3}\\ \end{bmatrix} \\ \begin{bmatrix} a_x\\ \color{red}a_{x-1}\\ a_{x-2} \end{bmatrix} = \begin{bmatrix} 1&0&1\\ \color{blue}1&\color{green}0&\color{orange}0\\ 0&1&0\\ \end{bmatrix} \cdot \begin{bmatrix} \color{blue}a_{x-1}\\ \color{green}a_{x-2}\\ \color{orange}a_{x-3}\\ \end{bmatrix} \\ \begin{bmatrix} a_x\\ a_{x-1}\\ \color{red}a_{x-2} \end{bmatrix} = \begin{bmatrix} 1&0&1\\ 1&0&0\\ \color{blue}0&\color{green}1&\color{orange}0\\ \end{bmatrix} \cdot \begin{bmatrix} \color{blue}a_{x-1}\\ \color{green}a_{x-2}\\ \color{orange}a_{x-3}\\ \end{bmatrix} \]

然后我们发现

\[\begin{bmatrix} a_x\\ a_{x-1}\\ a_{x-2} \end{bmatrix} =\begin{bmatrix} 1&0&1\\ 1&0&0\\ 0&1&0\\ \end{bmatrix} \cdot \begin{bmatrix} a_{x-1}\\ a_{x-2}\\ a_{x-3}\\ \end{bmatrix} \]

\[\begin{bmatrix} a_{x-1}\\ a_{x-2}\\ a_{x-3} \end{bmatrix} =\begin{bmatrix} 1&0&1\\ 1&0&0\\ 0&1&0\\ \end{bmatrix} \cdot \begin{bmatrix} a_{x-2}\\ a_{x-3}\\ a_{x-4}\\ \end{bmatrix} \]

于是考虑递归地将下面的式子带入到上面的式子,就有了

\[\begin{bmatrix} a_x\\ a_{x-1}\\ a_{x-2} \end{bmatrix} =\begin{bmatrix} 1&0&1\\ 1&0&0\\ 0&1&0\\ \end{bmatrix}^{x-3} \cdot \begin{bmatrix} a_{3}\\ a_{2}\\ a_{1}\\ \end{bmatrix} \]

发现这个是可以用矩阵快速幂快速计算的,并且比较容易。

我们把做快速幂的这个 \(3\times 3\) 的矩阵称作转移矩阵。

有些时候,在这个 \(A^{x-3}\) 的形式算完之后,因为 $$\begin{bmatrix}a_3\a_2\a_1\end{bmatrix}$$ 这个矩阵的形式比较简单,可以手动把这一步算出来,然后用 \(A\) 中的项直接表示出这次矩阵乘法的结果,代码会好写一些。

比如这道题目,可以计算出 \(A^{x-2}\) 的值,发现那么我们要求的 \(a_x\) 其实对应的就是目标矩阵的第二行那个数字(原图中 \(a_{x-1}\) 的位置),也就是 \(A_{2,1}\),就是这个转移矩阵的第二行的第一个数字。

关于写法的问题

可以发现其实上面的转移式还有一种写法

\[\begin{bmatrix} a_x&a_{x-1}&a_{x-2} \end{bmatrix} = \begin{bmatrix} a_{x-1}&a_{x-2}&a_{x-3} \end{bmatrix} \cdot \begin{bmatrix} 1&1&0\\ 0&0&1\\ 1&0&0 \end{bmatrix} \]

这样计算出来的意思是一样的。

(注意看这两种写法的转移矩阵是不一样的,准确来说做了个转置的操作。)

特别注意,在线段树维护矩阵的时候,两种写法的 pushup 操作是顺序不同的,后面会具体进行说明。

矩阵快速幂优化dp

那么我们考虑在大多数的 dp 中,转移的式子会写成这种形式

\(f_x=a_{x-1}f_{x-1}+a_{x-2}f_{x-2}+\dots +a_{x-k}f_{x-k}\)

这里的 \(a_{x-1}\) 这些系数对于每个 \(f_x\) 都是相同的,也就是说这些都是常数。

也可以说这个时候 \(f_x\) 为线性递推数列。

下面这句话不影响理解文章,可以选择跳过。

当然线性递推数列可以通过特征方程的方式求出通项公式,但是通向公式通常会带有根号导致无法直接计算,有时还有不可用根式表达的情况(Abel–Ruffini),还需要手动写出根号类运算支持根号的运算,也并不简单,并且在 mod 意义下(正确性存疑)。

考虑应用刚才的知识,类比方法

\[\begin{bmatrix} f_x\\ f_{x-1}\\ f_{x-2}\\ \vdots\\ f_{x-k+1} \end{bmatrix} = \begin{bmatrix} a_{x-1}&a_{x-2}&a_{x-3}&\cdots&a_{x-k+1}&a_{x-k}\\ 1&0&0&\cdots&0&0\\ 0&1&0&\cdots&0&0\\ \vdots&\vdots&\vdots&\vdots&\vdots&\vdots\\ 0&0&0&\cdots&1&0 \end{bmatrix} \cdot \begin{bmatrix} f_{x-1}\\ f_{x-2}\\ f_{x-3}\\ \vdots\\ f_{x-k} \end{bmatrix} \]

发现这个转移可以用这种形式来表示。

其实就是把原来 dp 转移的系数平推在第一行了。

但是并不是所有的 dp 的转移形式都长成这个样子,还有另外一种形式。

比如说有些 dp 的转移函数长成这个样子

\[dp_{i,j,k}=\sum a_{i-1,x,y}dp_{i-1,x,y} \]

\(j,k\) 这两位都不大。

那么这个时候就要把 \(j,k\) 压到一行上,然后做矩阵快速幂。

\(j\in\{0,1\},k\in\{0,1\}\) 举例子。

为了方便表示,下面记录 \(dp_{i,x,y}\)\(dp_{i-1,j,k}\) 的贡献为 \(f_{x,y,j,k}\),即 \(dp_{i,x,y}=\sum f_{x,y,j,k}dp_{i-1,j,k}\)

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

这个转移显然是成立的,注意一下和上面的矩阵是有区别的,实现的时候通常写一个函数 id(j,k) 确定矩阵上的位置。

这个题,就是 \(id(j,k)=2j+k,id(j,k)\in\{0,1,2,3\}\)

也就是 \((0,0)\) 对应这个矩阵的第一个位置,\((0,1)\) 对应这个矩阵的第二个位置,\((1,0)\) 对应这个矩阵的第三个位置...。

例子是 P5303 和 P5371。

注意到有些时候可能会有更多维度,矩阵乘法都压到一行上。

考虑矩阵是一个 \(n\times n\) 的,那么时间复杂度就是 \(n^3\log x\),其中 \(x\) 是要求 \(dp_x\) 的值,这里的 \(n^3\) 使用上文说过的优化方法(跳过 \(a_{i,j}=0\) 的位置)通常跑不满。

注意到有些时候矩阵可能会很大,比如 P5303 我的做法\(n\)\(40+\) , P5371 我的做法 \(n\)\(20+\),这个时候可以先写一个暴力的 dp ,然后把暴力 dp 的每个状态用上述方法映射到一个 id ,原来暴力 dp 的转移\(dp_{i,j,k,l}+=a\cdot dp_{i-1,j2,k2,l2}\),写成\(M_{id(j,k,l),id(j2,k2,l2)}+=a\)或者\(M_{id(j2,k2,l2),id(j,k,l)}+=a\),取决于你的写法是那种,矩阵乘向量还是向量乘矩阵。

这里\(M\)是转移矩阵,\(a\)是 dp 时的系数。

线段树维护矩阵乘法

注意到上文所说的矩阵快速幂维护的矩阵都有一个特点,就是 \(dp_i\)\(dp_{i-1}\) 的转移系数 \(a_{i,j}\) 是固定的,并不会因为 \(i\) 的变化而变化。

但是考虑下面这个问题。

P12087

给出一个很大的数(\(10^5\) 位量级),每次询问不大于这个数的不包含子串 13 的数有多少个。

到这里是可以使用树形 dp 进行维护的。

\(dp_{i,j,k}\) 表示处理完了前 \(i\) 位的情况,第 \(j\) 位是不是 \(1\),是否(\(k\))卡满了上届,后续一共有多少种填法。

转移可以考虑典型的树形 dp 的转移方法

int LIM;
if(lim)LIM=x[i+1]-'0';
else LIM=9;
for(int j=0;j<=LIM;++j){if(f and j==3)continue;(num+=dfs(i+1,(j==1),lim&(j==(x[i+1]-'0'))))%=mod;
}
return dp[i][f][lim]=num;

但是这个题目还有两个变化。

  • 查询区间 \([l,r]\) 直接组成一个数字,这个字问题的答案。
  • 修改原来的数字的某一位。

发现这一整个转移过程都可以使用上文提到的以 \(j\in\{0,1\},k\in\{0,1\}\) 举例子的部分用矩阵的方式表示出转移。

注意到转移和 \(a\) 的值有关,因此考虑使用线段树进行维护,每个节点都维护一个转移矩阵,线段树的性质可以支持单点修改矩阵和区间查询矩阵。

注意一个重要的细节
如果写法是

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

记录 \(x_n\) 为转移矩阵。

\[f_n=x_n f_{n-1}\\ f_{n-1}=x_{n-1} f_{n-2}\\ f_n=x_nx_{n-1}\cdots x_2 f_1 \]

你会发现这里的矩阵是从大下标一直乘到小下标的,而矩阵乘法是不具有交换律的,因此写成 pushup 的时候要记得写右子树矩阵乘左子树矩阵。

不过如果转移矩阵写成

\[\begin{bmatrix} dp_{i,0,0}&dp_{i,0,1}&dp_{i,1,0}&dp_{i,1,1} \end{bmatrix} = \begin{bmatrix} dp_{i-1,0,0}&dp_{i-1,0,1}&dp_{i-1,1,0}&dp_{i-1,1,1} \end{bmatrix} \cdot \begin{bmatrix} f_{0,0,0,0}&f_{0,1,0,0}&f_{1,0,0,0}&f_{1,1,0,0}\\ f_{0,0,0,1}&f_{0,1,0,1}&f_{1,0,0,1}&f_{1,1,0,1}\\ f_{0,0,1,0}&f_{0,1,1,0}&f_{1,0,1,0}&f_{1,1,1,0}\\ f_{0,0,1,1}&f_{0,1,1,1}&f_{1,0,1,1}&f_{1,1,1,1}\\ \end{bmatrix} \]

就不存在这种问题了,展开递推式子是按照小下标到大下标的顺序的,线段树直接按照 \(ls*rs\) 就是对的,在使用线段树维护矩阵的时候推荐这张写法。

线段树维护链上问题的矩阵乘法

有些时候,树上查询链的问题,将链看作一个数组,也能按照上文的方法进行矩阵优化。

那么就有一个思路,把树做一个树剖,将重链看作一个正常的数列用线段树维护,就能解决链上问题了。

注意链上问题要特别注意顺序,是向上走还是向下走,因为矩阵没有交换律。

例题,P14468,代码细节或许比较多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1198787.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qwen3-Embedding-4B性能评测:长文本嵌入速度实测对比

Qwen3-Embedding-4B性能评测&#xff1a;长文本嵌入速度实测对比 1. Qwen3-Embedding-4B介绍 Qwen3 Embedding 模型系列是 Qwen 家族中专为文本嵌入与排序任务打造的最新成员&#xff0c;基于强大的 Qwen3 系列基础模型构建。该系列覆盖了从 0.6B 到 8B 的多种参数规模&#…

手把手教你部署CV-UNet,5分钟实现智能去背

手把手教你部署CV-UNet&#xff0c;5分钟实现智能去背 1. 快速上手&#xff1a;什么是CV-UNet图像抠图&#xff1f; 你有没有遇到过这样的问题&#xff1a;想换一张照片的背景&#xff0c;但头发丝、肩膀边缘总是处理不好&#xff1f;手动用PS抠图太费时间&#xff0c;效果还…

fft npainting lama日志查看方法:定位错误信息实战教程

fft npainting lama日志查看方法&#xff1a;定位错误信息实战教程 1. 引言&#xff1a;为什么日志排查如此重要 在使用 fft npainting lama 进行图像修复、重绘或移除物品的过程中&#xff0c;你是否遇到过点击“开始修复”后毫无反应&#xff1f;或者系统提示“初始化失败”…

Qwen2.5-0.5B省钱方案:无GPU环境部署,按需计费更灵活

Qwen2.5-0.5B省钱方案&#xff1a;无GPU环境部署&#xff0c;按需计费更灵活 1. 轻量模型也能高效对话 你是不是也遇到过这样的问题&#xff1a;想用大模型做智能对话&#xff0c;但一看到GPU服务器的价格就望而却步&#xff1f;训练动辄几百上千的月租&#xff0c;推理还要常…

为什么选择cv_unet_image-matting?开源可商用优势深度解析

为什么选择cv_unet_image-matting&#xff1f;开源可商用优势深度解析 1. 开源图像抠图新选择&#xff1a;cv_unet_image-matting 实用价值解析 你是否正在寻找一款既能高效完成图像抠图&#xff0c;又无需支付高昂授权费用的工具&#xff1f;在当前AI图像处理技术快速发展的…

Live Avatar参数详解:从prompt到num_clip的调优手册

Live Avatar参数详解&#xff1a;从prompt到num_clip的调优手册 1. 引言&#xff1a;Live Avatar阿里联合高校开源的数字人模型 你有没有想过&#xff0c;只需要一张照片和一段音频&#xff0c;就能让静态人物“活”起来&#xff1f;阿里联合多所高校推出的Live Avatar项目&a…

FSMN-VAD支持MP3/WAV,格式兼容性强

FSMN-VAD支持MP3/WAV&#xff0c;格式兼容性强 在语音识别、会议记录转写、教学音频处理等实际应用中&#xff0c;一个常见但关键的预处理环节是语音端点检测&#xff08;Voice Activity Detection, VAD&#xff09;。它的作用是从一段包含静音或背景噪声的长音频中&#xff0…

YOLOv9来了!这个官方镜像让目标检测变得超级简单

YOLOv9来了&#xff01;这个官方镜像让目标检测变得超级简单 你是不是也经历过这样的场景&#xff1a;好不容易找到一个看起来很厉害的目标检测模型&#xff0c;结果光是配置环境就花了整整两天&#xff1f;CUDA版本不对、PyTorch装不上、依赖冲突报错满屏飞……还没开始训练&…

Llama3-8B与Phi-3对比:移动端适配性部署评测

Llama3-8B与Phi-3对比&#xff1a;移动端适配性部署评测 1. 引言&#xff1a;轻量大模型的落地之争 当前&#xff0c;AI 模型正从“越大越强”转向“够用就好”的实用主义阶段。尤其在移动端、边缘设备和消费级显卡场景下&#xff0c;如何在性能与资源之间取得平衡&#xff0…

verl算法扩展教程:几行代码自定义RL数据流

verl算法扩展教程&#xff1a;几行代码自定义RL数据流 1. 引言&#xff1a;为什么需要自定义RL数据流&#xff1f; 强化学习&#xff08;RL&#xff09;在大语言模型&#xff08;LLM&#xff09;后训练中的应用正变得越来越广泛。然而&#xff0c;传统RL框架往往结构僵化、扩…

Qwen3-4B内存泄漏?稳定性优化部署案例分享

Qwen3-4B内存泄漏&#xff1f;稳定性优化部署案例分享 1. 背景与问题引入 最近在本地部署 Qwen3-4B-Instruct-2507 的过程中&#xff0c;遇到了一个典型但容易被忽视的问题&#xff1a;模型运行一段时间后&#xff0c;显存占用持续上升&#xff0c;最终导致服务卡顿甚至崩溃。…

语音识别结果导出难?Speech Seaco Paraformer文本复制技巧详解

语音识别结果导出难&#xff1f;Speech Seaco Paraformer文本复制技巧详解 1. 为什么你的语音识别结果总是“看得见却拿不走”&#xff1f; 你有没有遇到过这种情况&#xff1a;花了几分钟上传音频&#xff0c;等系统识别完&#xff0c;终于看到那一段清晰的文字结果&#xf…

单麦语音去噪新选择|FRCRN语音降噪-16k镜像一键推理实践

单麦语音去噪新选择&#xff5c;FRCRN语音降噪-16k镜像一键推理实践 还在为会议录音里的键盘声、空调嗡鸣、街道车流而头疼&#xff1f;或是线上教学时学生背景里孩子的哭闹、宠物叫声让关键语音信息模糊不清&#xff1f;传统滤波方法对非平稳噪声束手无策&#xff0c;而多数开…

阿里联合高校开源Live Avatar:5分钟快速部署数字人模型

阿里联合高校开源Live Avatar&#xff1a;5分钟快速部署数字人模型 1. 快速上手&#xff1a;5分钟完成数字人模型部署 你有没有想过&#xff0c;只需要几分钟&#xff0c;就能让一个虚拟人物“活”起来——能说话、有表情、还能根据你的音频驱动做出自然动作&#xff1f;现在…

2026浙江机械油源头厂家实力盘点与推荐

在工业制造持续向高端化、智能化迈进的时代背景下,机械设备的稳定、高效、长周期运行已成为企业降本增效、提升核心竞争力的关键。作为设备的“血液”,机械油及工业润滑油的品质与技术适配性,直接决定了设备维护成本…

5分钟上手智谱Phone Agent,AI自动玩转小红书抖音

5分钟上手智谱Phone Agent&#xff0c;AI自动玩转小红书抖音 你有没有想过&#xff0c;让AI像真人一样操作你的手机&#xff1f;不是简单的语音唤醒&#xff0c;而是真正“看”懂屏幕、“点”进App、“搜”出内容&#xff0c;甚至帮你关注博主、点赞视频、查找攻略。听起来像科…

AI写真商业化落地指南:GPEN人像增强部署优化案例

AI写真商业化落地指南&#xff1a;GPEN人像增强部署优化案例 你是否遇到过老照片模糊、低清证件照无法使用&#xff0c;或者客户提供的原始人像质量太差影响成片效果&#xff1f;在摄影、写真、婚庆、电商等场景中&#xff0c;这类问题每天都在发生。而如今&#xff0c;AI人像…

Paraformer-large学术研究用途:论文数据集转写实战

Paraformer-large学术研究用途&#xff1a;论文数据集转写实战 1. 镜像核心能力与适用场景 在学术研究中&#xff0c;语音数据的整理和转写是一项耗时且繁琐的基础工作。无论是语言学访谈录音、课堂实录、临床对话记录&#xff0c;还是社会调查中的口头反馈&#xff0c;都需要…

Llama3-8B医疗问答试点:合规性与部署优化实战分析

Llama3-8B医疗问答试点&#xff1a;合规性与部署优化实战分析 1. 引言&#xff1a;为什么选择Llama3-8B做医疗问答试点&#xff1f; 在AI医疗的探索中&#xff0c;我们始终面临一个核心问题&#xff1a;如何在保障数据安全和模型能力之间取得平衡&#xff1f;大型闭源模型虽然…

sam3提示词引导分割模型上线|附Web交互式图像分割实践

sam3提示词引导分割模型上线&#xff5c;附Web交互式图像分割实践 1. 为什么说SAM3是图像分割的“新玩法”&#xff1f; 你有没有遇到过这种情况&#xff1a;想从一张照片里把某个物体单独抠出来&#xff0c;比如一只狗、一辆红色汽车&#xff0c;或者一件蓝色T恤&#xff0c…