热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

根据线性递推的DP公式如何写出变换矩阵

原理一组DP状态,其实等价于一个向量。而DP状态的转移方程,可以是对一个向量做变形的矩阵。那么本质上从1个向量到另一个状态的向量,是可以

原理

一组DP状态,其实等价于一个向量。而DP状态的转移方程,可以是对一个向量做变形的矩阵。那么本质上从1个向量到另一个状态的向量,是可以通过一个矩阵来做到。矩阵具有结合律,我们可以先对右半部分矩阵用快速幂得到一个终极的变形矩阵,再乘以向量,就可以把O(N)O(N)O(N)的计算 优化到 O(log(N))O (log(N))O(log(N))




示例

以大家最熟悉的斐波那契数列为例:

递推公式为 dp[i]=dp[i−1]+dp[i−2]dp[i] = dp[i-1] + dp[i - 2]dp[i]=dp[i1]+dp[i2],那么每一个新的数的计算依赖于前2个数,所以可以构建这么一个向量为 (dp[n−1],dp[n−2])(dp[n-1], dp[n-2])(dp[n1],dp[n2]),那么它和递推的下一组(dp[n],dp[n−1])(dp[n], dp[n-1])(dp[n],dp[n1])有什么关系呢?


  • dp[n]=dp[n−1]∗1+dp[n−2]∗1dp[n] = dp[n-1] *1+ dp[n - 2]*1dp[n]=dp[n1]1+dp[n2]1
  • dp[n−1]=dp[n−1]∗1=dp[n−1]∗1+dp[n−2]∗0dp[n-1] = dp[n-1]*1=dp[n-1] *1+ dp[n - 2]*0dp[n1]=dp[n1]1=dp[n1]1+dp[n2]0

转换为矩阵形式,显而易见:在这里插入图片描述
依次递推,要从 dp[2],dp[1]dp[2], dp[1]dp[2],dp[1]求到 dp[n],dp[n−1]dp[n], dp[n-1]dp[n],dp[n1] 中间需要有n-2个同样的变形矩阵的乘法

在这里插入图片描述
(此处若n比较大,则需要结合矩阵快速幂优化)

 传送门:矩阵快速幂优化

注:
本文部分引自西部小笼包https://www.jianshu.com/p/9817cf3c2fd9


推荐阅读
author-avatar
桃花救赎
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有