zoukankan      html  css  js  c++  java
  • 动态DP学习笔记

    在DP的时候,我们根据一些已知信息,推知局部最优解,再逐步“递推”推出全局最优解。

    虽然和动态DP没什么关系但我还想扯一句:DP的时候我们需要保证无后效性——当前状态确定后,之后的状态转移与之前的状态/决策无关。

    常规的DP是信息是不能修改的,但我们希望修改信息后,仍然知道全局最优解是多少。而且每次修改的复杂度要比较低

    例题:给你一个树,点有点权,求这棵树的最大权独立集是多少——也就是选出一个点集,使得其中点的权值和最大,且这些点之间没有边相连。有m次修改,每次修改一个点的权值,再询问一次答案。

    考虑转移方程:

    定义f(x,0/1)分别表示x这个点不选/选时,子树内的答案

    显然有:

    [f(x,0)=sum max(f(v,1),f(v,0)), f(x,1)=sum max(f(v,0)) ]

    但这个东西修改起来不太好做。。

    考虑静态树问题带修改的最经典做法——树链剖分,我们尝试把DP改成可以用树剖维护的形式

    额外定义g(x,0/1)表示在x的非重链所有子树中,x不选/选时的总答案

    设son表示x的重儿子

    [g(x,0)=sum_{v e son}max(f(v,0),f(v,1)) \ g(x,1)=a_{x}+sum_{v e son}f(v,0) \ f(x,0)=g(x,0)+max(f(son,0),f(son,1)) \ f(x,1)=g(x,1)+f(son,0) \ ]

    考虑怎么用矩阵维护它

    [egin{bmatrix} f(x,0)\ f(x,1) end{bmatrix} = egin{bmatrix} g(x,0) & g(x,0)\ g(x,1) & -inf end{bmatrix} * egin{bmatrix} f(son,0)\ f(son,1) end{bmatrix} ]

    我们重载了运算符!把*运算换成了+,+运算换成了max

    它的运算符合矩阵结合律!可以在线代书第6章找到然而UESTC的线代并没有讲这一章

    这么做为什么行?

    修改点x的权值时,受影响的只有从x到根的这一条链上的点

    中间那个矩阵可以用线段树维护一段矩阵相乘

    每次修改,最多涉及到log条树剖链

    x的所有祖先中,g函数受影响的只有 x到根路径上经历的每条树剖链和 后一条链岔口的那一个点y。至于变成什么,取决于它后一条链顶点的f函数。

    从x所在的树剖链一层层往上推,就能知道根节点的答案,也就是全局答案

    那么x所在的链怎么办?路径上某一点的f函数有点难求

    每条树剖链的最底端一定是叶节点!

    叶节点的f函数是确定的!我们直接问修改前后整条链的答案变化,就能修改y的g函数了

  • 相关阅读:
    169. Majority Element
    283. Move Zeroes
    1331. Rank Transform of an Array
    566. Reshape the Matrix
    985. Sum of Even Numbers After Queries
    1185. Day of the Week
    867. Transpose Matrix
    1217. Play with Chips
    766. Toeplitz Matrix
    1413. Minimum Value to Get Positive Step by Step Sum
  • 原文地址:https://www.cnblogs.com/guapisolo/p/14806629.html
Copyright © 2011-2022 走看看