动态规划——矩阵优化DP 学习笔记

这篇具有很好参考价值的文章主要介绍了动态规划——矩阵优化DP 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态规划——矩阵优化DP 学习笔记

前置知识:矩阵、矩阵乘法。

矩阵乘法优化线性递推

斐波那契数列

在斐波那契数列当中,\(f_1 = f_2 = 1\)\(f_i = f_{i - 1} + f_{i - 2}\),求 \(f_n\)

而分析式子可以知道,求 \(f_k\) 仅与 \(f_{k - 1}\)\(f_{k - 2}\) 有关;
所以我们设矩阵 \(F_i = \begin{bmatrix} f_{i - 1} & f_{i - 2} \end{bmatrix}\)

设矩阵 \(\text{Base}\),使得 \(F_{i - 1} \times \text{Base} = F_i\),接下来考虑 \(\text{Base}\) 是什么;
带入可得 \(\begin{bmatrix} f_{i - 2} & f_{i - 3} \end{bmatrix} \times \text{Base} = \begin{bmatrix} f_{i - 1} & f_{i - 2} \end{bmatrix}\)

\(\begin{bmatrix} f_{i - 2} & f_{i - 3} \end{bmatrix} \times \text{Base} = \begin{bmatrix} f_{i - 2} + f_{i - 3} & f_{i - 2} \end{bmatrix}\)
根据矩阵乘法的规则可知 \(\text{Base}\) 的第 \(1\) 列应为 \(\begin{bmatrix} 1 & 1 \end{bmatrix}^\text{T}\),第 \(2\) 列应为 \(\begin{bmatrix} 1 & 0 \end{bmatrix}^\text{T}\)

所以求得 \(\text{Base} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}\)

然后考虑 \(f_i\) 的值应该是多少;
根据前面的公式可以知道 \(f_i = F_{n + 1}\) 的第一个数,所以就是求这个数。

根据 \(f_1 = f_2 = 1\),可以知道 \(F_3 = \begin{bmatrix} f_2 & f_1 \end{bmatrix} = \begin{bmatrix} 1 & 1 \end{bmatrix}\),我们将这个作为边界值;
然后有 \(F_4 = F_3 \times \text{Base}\)\(F_5 = F_4 \times \text{Base} = F_3 \times \text{Base} \times \text{Base}\)

因为矩阵乘法有结合律,所以 \(F_{n + 1} = F_3 \times \text{Base}^{n - 2} = \begin{bmatrix} 1 & 1 \end{bmatrix} \times \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{n - 2}\)

因为矩阵没有交换律,所以 \(F_3\)(前)和 \(\text{Base}^{n - 2}\)(后)一定不能写反了!

例题1

\(\left\{\begin{array}{l} f_1 = f_2 = 0 \\ f_i = f_{i - 1} + f_{i - 2} + 1 \end{array}\right.\)

点击查看题解

\(f_i\) 仅与 \(f_{i - 1}\)\(f_{i - 2}\) 有关,同时还包括了常数 \(1\)
所以我们设 \(F_i = \begin{bmatrix} f_{i - 1} & f_{i - 2} & 1 \end{bmatrix}\)

然后设 \(\text{Base}\) 使得 \(F_{i - 1} \times \text{Base} = F_i\)
\(\begin{bmatrix} f_{i - 2} & f_{i - 3} & 1 \end{bmatrix} \times \text{Base} = \begin{bmatrix} f_{i - 1} & f_{i - 2} & 1 \end{bmatrix}\)

因为 \(f_{i - 1} = f_{i - 2} + f_{i - 3} + 1\),所以易知:

\(\text{Base} = \begin{bmatrix} 1 & 1 & 0 \\ 1 & 0 & 0 \\ 1 & 0 & 1 \end{bmatrix}\).

边界条件为 \(F_3 = \begin{bmatrix} 0 & 0 & 1\end{bmatrix}\)
所以 \(F_{n + 1} = F_3 \times \text{Base}^{n - 2}\)

即可求出 \(f_n\).

例题2

\(\left\{\begin{array}{l} f_1 = 0 \text{,} f_2 = 1 \\ f_i = f_{i - 1} + f_{i - 2} + i \end{array}\right.\)

点击查看题解

\(f_i\) 仅与 \(f_{i - 1}\)\(f_{i - 2}\)\(i\) 有关,为实现 \(i\) 的递增,还需设置常量 \(1\)
所以我们设 \(F_i = \begin{bmatrix} f_{i - 1} & f_{i - 2} & i & 1 \end{bmatrix}\)

\(F_{i - 1} \times \text{Base} = F_i\)\(\text{Base} = \begin{bmatrix} 1 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 1 & 0 & 1 & 0 \\ 0 & 0 & 1 & 1 \end{bmatrix}\).

边界条件为 \(F_3 = \begin{bmatrix} 1 & 0 & 3 & 1 \end{bmatrix}\).

\(F_{n + 1} = F_3 \times \text{Base}^{n - 2}\);即可求出 \(f_n\)

例题3(来自 OI-Wiki)

\(\left\{\begin{array}{l} f_{1} = f_{2} = 0 \\ f_{n} = 7f_{n-1}+6f_{n-2}+5n+4\times 3^n \end{array}\right.\)

点击查看题解

我的解法与 OI-Wiki 上的有所不同:

\(F_n = \begin{bmatrix} f_{n - 1} & f_{n - 2} & n & 3^n & 1 \end{bmatrix}\).

易知 \(\text{Base} = \begin{bmatrix} 7 & 1 & 0 & 0 & 0 \\ 6 & 0 & 0 & 0 & 0 \\ 5 & 0 & 1 & 0 & 0 \\ 4 & 0 & 0 & 3 & 0 \\ 0 & 0 & 1 & 0 & 1 \end{bmatrix}\).

边界值 \(F_3 = \begin{bmatrix} 0 & 0 & 3 & 27 & 1 \end{bmatrix}\).

\(F_{n + 1} = F_3 \times \text{Base}^{n - 2}\).

例题4

\(\left\{\begin{array}{l} f_1 = f_2 = 0 \text{,} f_3 = 1 \\ f_i = 3f_{i - 1} + 2f_{i - 2} + f_{i - 3} + 5i + 7 \end{array}\right.\)

点击查看题解

增加了 \(f_{i - 3}\),但是本质是一样的。

可以设 \(F_i = \begin{bmatrix} f_{i - 1} & f_{i - 2} & f_{i - 3} & i & 1 \end{bmatrix}\)

易得 \(\text{Base} = \begin{bmatrix} 3 & 1 & 0 & 0 & 0 \\ 2 & 0 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 \\ 5 & 0 & 0 & 1 & 0 \\ 7 & 0 & 0 & 1 & 1 \end{bmatrix}\).

\(F_4 = \begin{bmatrix} 1 & 0 & 0 & 4 & 1 \end{bmatrix}\)

\(F_{n + 1} = F_4 \times \text{Base}^{n - 3}\)

例题5

洛谷 P1939 矩阵加速(数列):https://www.luogu.com.cn/problem/P1939

考虑这道题 \(\text{Base}\) 该如何设置。

点击查看代码
const long long MOD = 1e9 + 7;

struct matrix
{
    long long a[4][4];
    matrix operator*(const matrix &t) const
    {
        matrix res;
        memset(res.a, 0, sizeof res.a);
        for (int i = 1; i <= 3; ++i)
            for (int j = 1; j <= 3; ++j)
                for (int k = 1; k <= 3; ++k)
                    res.a[i][j] = (res.a[i][j] + a[i][k] * t.a[k][j] % MOD) % MOD;
        return res;
    }
};

int main()
{
    int T = rr;
    while (T--)
    {
        int n = rr;

        if (n <= 3)
        {
            printf("1\n");
            continue;
        }

        matrix Base = {{{0, 0, 0, 0},
                        {0, 1, 1, 0},
                        {0, 0, 0, 1},
                        {0, 1, 0, 0}}};
        matrix res = {{{0, 0, 0, 0},
                       {0, 1, 0, 0},
                       {0, 0, 1, 0},
                       {0, 0, 0, 1}}};

        int k = n - 3;
        while (k)
        {
            if (k & 1)
                res = res * Base;
            k >>= 1, Base = Base * Base;
        }

        printf("%lld\n", (res.a[1][1] + res.a[2][1] + res.a[3][1]) % MOD);
    }

    return 0;
}

时间复杂度

矩阵乘法 \(O(k^3)\) 其中 \(k\) 为矩阵的长(或宽);
快速幂 \(O(\log n)\)

所以[矩阵乘法优化线性递推]的时间复杂度为 \(O(k^3 \log n)\)

矩阵乘法优化 DP

朴素矩阵乘法

\(\mathrm{dp}[t][x][y] = \sum\limits_{w = 1}^n \mathrm{dp}[t][x][w] \times G[w][y]\)

则可以看为矩阵乘法的形式:\(\mathrm{dp}_t = \mathrm{dp}_{t - 1} \times G\),即 \(\mathrm{dp}_t = Ans_0 \times G^t\)

广义矩阵乘法

对矩阵的乘法重载,即可用快速幂求解了。

具体的,可以看这篇文章:https://www.luogu.com.cn/blog/i207M/xie-ti-bao-gao-sp1716-gss3-can-you-answer-these-queries-iii。

多组询问的矩阵乘法优化 DP

例题:P6569 魔法值

我们要求一个 \(\mathrm{Ans}_k = \mathrm{Ans}_0 \times \mathrm{Mp}^k\),其中 \(\mathrm{Ans}_i\) 是一个长度为 \(n\) 的行向量。

那么,我们先预处理 \(\mathrm{Mp}^k\),即 \(\mathrm{Mp}^{2^i}\)

然后我们就是在求一个行向量和 \(\log_2 k\)\(n \times n\) 的矩阵的乘积了。

在算答案的时候,我们先别算这 \(\log_2 k\) 个方阵的乘积,先用 \(\mathrm{Ans}_0\) 向量从左乘到右。

因为向量乘矩阵复杂度是 \(O(n^2)\) 的!

这样复杂度就从 \(O(q \times n^3 \log_2 t)\),变成了 \(O(n^3 \log_2 t+q \times n^2 \log_2 t)\)

练习题

见:https://www.luogu.com.cn/training/385249

Reference

[1] https://oi-wiki.org/math/linear-algebra/matrix/
[2] https://www.cnblogs.com/ningago/p/17472070.html
[3] https://www.cnblogs.com/luckyblock/p/14430820.html
[4] http://blog.tsawke.com/Data/Blog/content/DDP.html
[5] https://blog.csdn.net/qq_41739081/article/details/128184363文章来源地址https://www.toymoban.com/news/detail-711848.html

到了这里,关于动态规划——矩阵优化DP 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划——状压DP 学习笔记

    前置知识:位运算 动态规划的过程是随着阶段的增长,在每个状态维度上不断扩展的。 在任意时刻,已经求出最优解的状态与尚未求出最优解的状态在各维度上的分界点组成了 DP 扩展的“轮廓”。对于某些问题,我们需要在动态规划的“状态”中记录一个集合,保存这个“

    2024年02月08日
    浏览(42)
  • 动态规划——树形DP 学习笔记

    前置知识:树基础。 树形 DP,即在树上进行的 DP,最常见的状态表示为 (f_{u,cdots}) ,表示以 (u) 为根的子树的某个东东。 本文将讲解一些经典题目(树的子树个数、树的最大独立集、树的最小点覆盖、树的最小支配集、树的直径、树的重心、树的中心),以及一些常见形

    2024年02月08日
    浏览(27)
  • 动态规划——数位DP 学习笔记

    引入 数位 DP 往往都是这样的题型:给定一个区间 ([l, r]) ,求这个区间中满足某种条件的数的总数。 简单的暴力代码如下: 而当数据规模过大,暴力枚举就 (mathbb T) 飞了,因此引入数位 DP: 概念 数位(digit):对于十进制,即把一个数字按照个位、十位、百位等,一位

    2024年02月08日
    浏览(38)
  • 动态规划算法学习一:DP的重要知识点、矩阵连乘算法

    三部曲如下三步: 基本原则:“空间换时间” 存储重复子问题的解,减少运算时间 底层运算:“表格操作” 用表格存储子问题的解 实现路线:“子问题划分、自底向上求解” 利用表格中存储的子问题的解,求上一层子问题的解。 矩阵连乘计算次序 可以用 加括号的方式

    2024年02月09日
    浏览(29)
  • AcWing算法学习笔记:动态规划(背包 + 线性dp + 区间dp + 计数dp + 状态压缩dp + 树形dp + 记忆化搜索)

    算法 复杂度 时间复杂度0(nm) 空间复杂度0(nv) 代码 算法 通过滚动数组对01背包朴素版进行空间上的优化 f[i] 与 f[i - 1]轮流交替 若体积从小到大进行遍历,当更新f[i, j]时,f[i - 1, j - vi] 已经在更新f[i, j - vi]时被更新了 因此体积需要从大到小进行遍历,当更新f[i, j]时,f[i - 1,

    2024年02月21日
    浏览(34)
  • 15.动态规划:数据结构优化DP

    数据结构优化DP有前缀和、滑动窗口、树状数组、线段树、单调栈、单调队列 中等 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如, [3,6,2,7] 是数组 [0,3,1,6,2,2

    2024年02月03日
    浏览(37)
  • 从01背包开始动态规划:暴力解法 + dp + 滚动数组 + dp优化

        01背包问题是动态规划中最经典的问题之一,本篇将通过给出其四种解法,使读者更深刻理解动态规划。   有N件物品和一个容量是 V 的背包,每个物品有各自的体积和价值,且每个物品只能放一次(这也是01背包名字的由来),如何让背包里装入的物品具有最大的价值总

    2024年04月17日
    浏览(40)
  • 【优化数学模型】2. 动态规划DP方法的求解思路

    多阶段决策问题,就是要在允许的决策范围内,选择一个最优决策使整个系统在预定标准下达到最佳效果。 动态规划 (dynamic programming,DP) 是用来解决多阶段决策过程最优化的一种数量方法。其特点在于,它可以把一个n维决策问题变换为几个一维最优化问题,从而一个一个地去

    2024年02月21日
    浏览(30)
  • 动态规划(DP)(算法笔记)

    本文内容基于《算法笔记》和官方配套练题网站“晴问算法”,是我作为小白的学习记录,如有错误还请体谅,可以留下您的宝贵意见,不胜感激。 动态规划(Dynamic Programming,DP)是一种用来解决一类最优化问题的算法思想。简单来说,动态规划将一个复杂的问题分解成若干个子

    2024年02月05日
    浏览(33)
  • 【状态机dp 动态规划】100290. 使矩阵满足条件的最少操作次数

    动态规划汇总 状态机dp 给你一个大小为 m x n 的二维矩形 grid 。每次 操作 中,你可以将 任一 格子的值修改为 任意 非负整数。完成所有操作后,你需要确保每个格子 grid[i][j] 的值满足: 如果下面相邻格子存在的话,它们的值相等,也就是 grid[i][j] == grid[i + 1][j](如果存在)

    2024年04月24日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包