对动态 DP 和全局平衡二叉树的一点补充解释

这篇具有很好参考价值的文章主要介绍了对动态 DP 和全局平衡二叉树的一点补充解释。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明:最近在帮高中竞赛教练写讲义,这是本人对讲义中动态 DP 内容的补充解释(因为主要是对知识点的理解,不太容易用通用的语言表述,也不适合作为讲义内容供读者阅读,所以用的是补充注释的形式)。写的比较抽象也比较初等,仅供意会

1. 为什么用矩阵表示转移

我们先从一般的角度,用映射的语言来表示 DP。以序列 DP 为例,假设 \(\{ \mathrm{dp}_{i}\}\) 是 DP 值数组,\(\left\{ a_{i} \right\}\) 是每个位置的信息(说明:DP 值数组可以是 \((f_i,g_i)\) 这样不止一个的;每个位置的信息 \(a_i\) 也不一定代表权值,也可以是 \((i,a_i,b_i,c_i,...)\) 这样更加复杂的信息)。

那么通常来说,一个 DP 的转移过程可以表示为如下关系式:

\[\left( \mathrm{dp}_{n},\ \mathrm{dp}_{n - 1},\ldots,\mathrm{dp}_{n - k + 1} \right) = T_{a_{n}}(\mathrm{dp}_{n - 1},\ \mathrm{dp}_{n - 2},\ldots,\mathrm{dp}_{n - k}) \]

其中 \(T_{a_{n}}\) 是一个由 \(a_{n}\) 决定的映射,表示用 \((\mathrm{dp}_{n - 1},\ \mathrm{dp}_{n - 2},\ldots,\mathrm{dp}_{n - k})\) 这些 DP 值能够确定 \(\mathrm{dp}_{n}\) 的值(将函数值写成 \(k\) 元组只是为了方便下文书写)。

这里 \(k\) 表示 \(\mathrm{dp}_{n}\) 由前面 \(k\) 个已知的 DP 值确定。在例题 1(区间最大子段和)中 \(k = 1\),即表示 \(\mathrm{dp}_{n}\) 只与 \(\mathrm{dp}_{n - 1}\) 有关,在斐波那契数列的递推关系中就可以认为是 \(k = 2\)。那么我们容易知道:

\[\begin{aligned}\left( \mathrm{dp}_{n},\ \mathrm{dp}_{n - 1},\ldots,\mathrm{dp}_{n - k + 1} \right) &= T_{a_{n}}\left( T_{a_{n - 1}}\left( \ldots\left( T_{a_{k + 1}}\left( \mathrm{dp}_{k},\mathrm{dp}_{k - 1},\ldots,\mathrm{dp}_{1} \right) \right) \right) \right) \\&= \left( T_{a_{n}} \circ T_{a_{n - 1}} \circ \cdots \circ T_{a_{k + 1}} \right)(\mathrm{dp}_{k},\mathrm{dp}_{k - 1},\ldots,\mathrm{dp}_{1})\end{aligned}\]

这里 \(\circ\) 表示映射的复合运算,而 \(\left( \mathrm{dp}_{k},\mathrm{dp}_{k - 1},\ldots,\mathrm{dp}_{1} \right)\) 可以认为就是 DP 的初值。

有时,为了快速计算最终的答案 \(\mathrm{dp}_{n}\),我们会利用映射的特殊性质,试图求出 \(T_{a_{n}} \circ T_{a_{n - 1}} \circ \cdots \circ T_{a_{k + 1}}\) 的表达式,进而计算。以斐波那契数列的递推关系为例,

\[\begin{bmatrix} {\mathrm{dp}}_{n} \\ {\mathrm{dp}}_{n - 1} \\ \end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \\ \end{bmatrix}\begin{bmatrix} \mathrm{dp}_{n - 1} \\ {\mathrm{dp}}_{n - 2} \\ \end{bmatrix}\]

此时就相当于 \(T\left( \begin{bmatrix} \mathrm{dp}_{n - 1} \\ {\mathrm{dp}}_{n - 2} \\ \end{bmatrix} \right) = \begin{bmatrix} 1 & 1 \\ 1 & 0 \\ \end{bmatrix}\begin{bmatrix} \mathrm{dp}_{n - 1} \\ {\mathrm{dp}}_{n - 2} \\ \end{bmatrix} = \begin{bmatrix} {\mathrm{dp}}_{n} \\ {\mathrm{dp}}_{n - 1} \\ \end{bmatrix}\)

更一般地,所有齐次线性递推转移方程其实都可以将DP转移表示为一个矩阵乘法,此时求映射复合就相当于求矩阵乘积,这就是矩阵快速幂优化线性递推的一种解释。

对于更常见的最优化DP,有时也可以用类似的思路处理。比如例1的区间最大子段和,转移就可以描述为:

\[T_{a_{n}}\begin{pmatrix} f_{n - 1} \\ g_{n - 1} \\ \end{pmatrix} = \begin{pmatrix} \max\left\{ f_{n - 1} + a_{n},a_{n} \right\} \\ \max\left\{ f_{n - 1} + a_{n},a_{n},g_{n - 1} \right\} \\ \end{pmatrix} = \begin{pmatrix} f_{n} \\ g_{n} \\ \end{pmatrix}\]

\(\left( \max, + \right)\) 广义矩阵乘法,可以将其写为矩阵乘法的形式,此处不再重复。写为矩阵乘法后,就利用矩阵乘法的结合律,进而用数据结构维护。

以上虽然都是用矩阵乘法的形式处理,但实质上,是因为这些转移对应的映射 \(\mathbf{T}\) 以及映射的复合都满足某些特殊性质,进而才能够用矩阵表示。回顾例 1 的另一种线段树做法,维护区间和、区间最大前缀和、最大后缀和、最大子段和这四个信息,其实就是在维护转移映射合并后的结果,所以它虽然没有显式出现矩阵乘法,但其实也能算作动态DP。

一般来说,如果转移对应的映射及其复合(或者说多个转移"合并"后)能够满足某些特殊性质,使其能够用少量信息表示(例如例1的四个区间信息,再例如若干次线性递推能够用多个矩阵的乘积表示),并且合并过程也比较容易,我们就能够用分治思想来对这些映射进行复合运算。体现在线性递推上,就是矩阵快速幂;如果带修改,那么用线段树就能很方便地维护一个映射变化,造成的复合运算结果的改变。

其中,能够分治计算依赖的是映射复合的结合律(这是自然成立的)。而真正需要注意的其实并非结合律,而是满足"特殊性质"映射对复合运算的"封闭性"(此处略去解释)。【所以,矩阵只是一种易于理解、易于推导的转移形式,矩阵乘法并不是本质的,分治思想才是解决问题的核心】

2. 如何将序列问题的解法迁移到树上问题

上文提到的方法只针对序列 DP,对于树上问题,我们通常是采用链分治的方式。对于一条重链,将每个结点轻儿子的信息合并到这个结点上(视作这个结点的信息),然后就可以在重链上用序列 DP 的方式处理了。

至于链分治的具体方式,就有三种常见方法(树剖+线段树;LCT;全局平衡二叉树),其中全局平衡二叉树的理论复杂度和实际表现都最优。

链分治的思想也可以迁移到更广泛的问题,例如链分治FFT解决部分计数问题、链分治闵可夫斯基和解决凸性DP问题(典例——树上最大边权k-匹配问题CFGym 102331J)。解决这些问题应用到的核心性质是——经过重链条数 / 全局平衡二叉树深度为 \(O(\log n)\)

这里补充说明一点:全局平衡二叉树实际上就是在重链剖分基础上,将“将重链分为两半”的分治方式,变成了“按照轻儿子的总 size + 1 为权重来分重链”的分治方式。而具体的维护细节(只是分治而不需要保留结构 or 需要用数据结构维护分治结构;线段树 or 平衡树;是否 leafy)和树链剖分都是没有实际区别的。文章来源地址https://www.toymoban.com/news/detail-679775.html

到了这里,关于对动态 DP 和全局平衡二叉树的一点补充解释的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 算法刷题Day 17 平衡二叉树+二叉树的所有路径+左叶子之和

    计算左右两棵子树的高度,如果有一个高度是-1(有一棵子树不平衡),直接返回-1,否则计算高度差,判断是否不平衡 使用 回溯 的方法,每次处理一个节点之前要把它push进table里,处理完之后又要把它pop出来 处理一个节点时,要判断它是否是左节点(需要父节点,可以通

    2024年02月15日
    浏览(43)
  • day17 | 110.平衡二叉树、 257. 二叉树的所有路径、 404.左叶子之和

    目录: 题目链接: https://leetcode.cn/problems/balanced-binary-tree/ https://leetcode.cn/problems/binary-tree-paths/ 110. 平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示

    2024年02月08日
    浏览(42)
  • 数据结构——常见二叉树的分类(完全二叉树、满二叉树、平衡二叉树、二叉搜索树、红黑树)

    专业术语 中文 描述 Root 根节点 一棵树的顶点 Child 孩子结点 一个结点含有的子树的根节点称为该结点的子节点 Leaf 叶子结点 没有孩子的节点 Degree 度 一个节点包含子树的数量 Edge 边 一个节点与另外一个节点的连接 Depth 深度 根节点到这个节点经过边的数量 Height 节点高度 从

    2024年02月03日
    浏览(44)
  • Day17|leetcode 110.平衡二叉树、257.二叉树的所有路径、404.左叶子之和

    题目链接:110. 平衡二叉树 - 力扣(LeetCode) 视频链接:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树_哔哩哔哩_bilibili 平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 本题就是求左右子树的高度差,如果差值=1,就是平衡

    2024年02月11日
    浏览(42)
  • PTA练习4.2 平衡二叉树的根 (25 分)

    题干 将给定的一系列数字插入初始为空的AVL树,请你输出最后生成的AVL树的根结点的值。 输入格式: 输入的第一行给出一个正整数N(≤20),随后一行给出N个不同的整数,其间以空格分隔。 输出格式: 在一行中输出顺序插入上述整数到一棵初始为空的AVL树后,该树的根结点

    2023年04月08日
    浏览(33)
  • 算法训练day17leetcode110平衡二叉树257二叉树的所有路径404左叶子之和

    https://www.bilibili.com/video/BV1GY4y1K7z8/?vd_source=8272bd48fee17396a4a1746c256ab0ae https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html#%E6%80%9D%E8%B7%AF 采用后序递归遍历,比较左右子树的高度,相差小于等于1 前序,中左右,从根节点到叶子节点,会一直向下遍历下去,不会返回信

    2024年01月19日
    浏览(44)
  • 数据结构课设(五)二叉排序树与平衡二叉树的实现

    假定二叉排序树与平题所处理数据均为整型。分别采用二叉链表和顺序表作存储结构,实现对二叉衡二叉树的操作。具体要求如下: (1)用二叉链表作存储结构: ①读入一个整数序列L(要求该整数序列从磁盘文件读取),生成一棵二叉排序树②对二叉排序树T作中序遍历,输出结果

    2024年02月12日
    浏览(46)
  • 数据结构学习记录——平衡二叉树的调整(基本介绍、右单旋、左单旋、左右双旋、右左双旋、平衡因子的计算)

    目录 基本介绍 右单旋 左单旋 左右双旋 右左双旋  平衡因子的计算 首先,平衡二叉树也是一棵二叉搜索树。 当我们在一棵平衡二叉树进行插入或者删除时,可能会把原来的平衡二叉树变得不平衡, 这个时候我们就需要进行调整了。 平衡二叉树的调整主要分为四大类: RR旋

    2023年04月27日
    浏览(38)
  • 有n个结点的平衡二叉树的最小、最大深度,及深度的数量级

    求有n个结点的平衡二叉树的深度范围: 1. 求有n个结点的平衡二叉树的最小深度 显然,n个结点的平衡二叉树深度最小时,前h-1层是满的,只有最下面一层不满。这样的树类似完全二叉树,其高度也可以通过类似求n个结点完全二叉树高度的方法求出。 n个结点的这样的树的深

    2024年02月06日
    浏览(43)
  • 数据结构:搜索二叉树 | 平衡二叉树

    博客写的代码都放在这里:gitee仓库链接 1.二叉搜索树 1.1.基本概念 二叉搜索树又称二叉排序树, 可以为空,如果不为空具有以下性质的二叉树 : 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的

    2024年01月23日
    浏览(58)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包