zoukankan      html  css  js  c++  java
  • 动态DP

    例题【洛谷P4719

    给定一棵树,节点$x$的权值为$w[x]$,维护以下两个操作:

    1. 修改一个节点的权值;

    2. 询问当前的最大独立集的权值。

    解:

    假设没有修改操作,则是一个典型的树形动态规划。设$f[x][0]$表示未选择节点$x$的情况下的最大权值,$f[x][1]$表示选择了节点$x$的情况下的最大权值,则

    $$ f[x][0] = sum_{y in ext{son}(x)} max{f[y][0], f[y][1]}, $$

    $$ f[x][1] = w[x] + sum_{y in ext{son}(x)} f[y][0]. $$

    特别地,若$x$是叶子节点,则$f[x][0] = 0, f[x][1] = w[x]$.

    将这棵树树链剖分后,令$ ext{heavy}(x)$表示节点$x$的重儿子,$ ext{light}(x)$表示节点$x$的轻儿子的集合。若$x$非叶节点,则

    $$ f[x][0] = max{ f[ ext{heavy}(x)][0], f[ ext{heavy}(x)][1] } + g[x][0], $$

    $$ f[x][1] = f[ ext{heavy}(x)][0] + g[x][1], $$

    其中

    $$ g[x][0] = sum_{y in ext{lignt}(x)} max{f[y][0], f[y][1]}, $$

    $$ g[x][1] = w[x]+ sum_{y in ext{lignt}(x)} f[y][0]. $$

    我们引入广义矩阵乘法,其加法为$max$,其乘法为$+$,对于两个矩阵$A$和$B$,其积$C = A*B$定义为

    $$C_{ij} = max_k {A_{ik}+B_{kj}}.$$

    我们可以把节点$x$与其重儿子$ ext{heavy}(x)$的动态规划递推式写作

    $$ egin{bmatrix} f[x][0] \ f[x][1] end{bmatrix} = egin{bmatrix} g[x][0] & g[x][0] \ g[x][1] & -infty end{bmatrix} * egin{bmatrix} f[ ext{heavy}(x)][0] \ f[ ext{heavy}(x)][1] end{bmatrix}. $$

    我们记

    $$ M[x] = egin{bmatrix} g[x][0] & g[x][0] \ g[x][1] & -infty end{bmatrix}. $$

    设$x = x_0 o x_1 o dots o x_k$是以$x$出发的重链,则以$x$为根的子树的最大独立集的权值可通过下式给出:

    $$ egin{bmatrix} f[x][0] \ f[x][1] end{bmatrix} = M[x_0] * M[x_1] * dots * M[x_{k-1}] * egin{bmatrix} 0 \ w[x_k] end{bmatrix}. $$

    这个式子可以写得更优美一点:

    $$ egin{bmatrix} f[x][0] \ f[x][1] end{bmatrix} = M[x_0] * M[x_1] * dots * M[x_k] * egin{bmatrix} 0 \ 0 end{bmatrix}. $$

    对于修改节点$x$的权值,我们只需要修改 $g[x][0], g[x][1]$ 以及节点$x$到根的路径中与其他重链交汇的那些节点,最多$O(log n)$个。

    故树链剖分能在$O(log^2n)$的复杂度内维护单次操作。

    P.S. 可以利用动态树(Link-Cut Tree)把复杂度进一步降为单次操作$O(log n)$。甚至还可以维护其他操作,如修改一个节点的父节点,以及询问某个子树的最大独立集等。

    然而这种神奇的动态DP居然在NOIP2018的Day2第三题【保卫王国】出现了。这也太超纲了吧,NOI2018的Day2第三题还差不多。

    不一样的是,【保卫王国】求的是最小点集覆盖。但二分图中,最小点集覆盖 = 权值之和 - 最大独立集。因此两个问题的求解是等价的。

    动态DP例题:

    洛谷P4719

    NOIP2018. 保卫王国

    CEOI2019. Dynamic Diameter

  • 相关阅读:
    软件编写和设计中的18大原则
    Ubuntu CTRL+ALT+F1~F6 进入命令模式后不支持中文显示的解决办法
    BM串匹配算法
    KMP串匹配算法解析与优化
    mongodb随机查询一条记录的正确方法!
    这真的该用try-catch吗?
    计算机的本质与数值、文字、声音、图像
    编程语言的概念
    linux服务方式启动程序脚本(init.d脚本)
    linux的7种运行级别
  • 原文地址:https://www.cnblogs.com/TinyWong/p/11227272.html
Copyright © 2011-2022 走看看