zoukankan      html  css  js  c++  java
  • 洛谷$P3647 [APIO2014]$连珠线 换根$dp$

    正解:换根$dp$

    解题报告:

    传送门!

    谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$

    考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如"父-子-孙"这样的.

    所以先考虑一个$O(n^2)$的做法,就枚举根节点,然后跑个$dfs$,设$f_{i,1}$表示点$i$是蓝线上"子"的最大答案,$f_{i,0}$表示点$i$不是蓝线上"zi"的最大答案

    然后对于$f_{i,0}$,它不是"子"有两种可能,要么就子节点是"子",就会是$f_{j,1}+w$,要么就连接的不是蓝线,此时$j$也不可能是"zi"了,就会是$f_{j,0}$

    然后对于$f_{i,1}$.考虑枚举哪个子节点是"孙".其他儿子和$f_{i,0}$的转移是一样的,只有点$j$的贡献从$max{f_{j,1}+w,f_{j,0}}$成了$f_{j,0}+w$

    所以转移就

    $f_{i,0}=sum max{f_{j,1}+w,f_{j,0}}$

    $f_{i,1}=max{f_{i,0}-max{f_{j,1}+w,f_{j,0}}+f_{j,0}+w}$

    发现复杂度很假,考虑优化.

    发现如果移动根对大部分节点无影响,所以考虑换根$dp$.

    现在考虑把某个节点的儿子变成了父亲有什么影响$QwQ$?

    首先这个子节点的贡献没了,所以$max$可能会改变,所以要记录一个次大值.同时原来的父亲变成了儿子对当前父亲产生了贡献.

    考虑在第一次$dp$的时候再记录一个$g_{i,j,0/1}$表示点$i$的子树中不考虑$j$的情况下的$f_{i,0/1}$.

    $g_{i,j,0}$就直接减去$max{f_{j,1}+w,f_{j,0}}$就成.

    然后$g_{i,j,1}$就顺便维护一个次大值,如果等于最大值就赋值为次大值,否则对最大值没有影响就依然赋值为最大值就好(同样要把$max{f_{j,1}+w,f_{j,0}}$的贡献删去鸭$QwQ$

    $code$

  • 相关阅读:
    雷林鹏分享:Lua 运算符
    雷林鹏分享:PHP JSON
    不要提交代码到HEAD上
    Mr Cao 的提问
    使用masory
    git 下载单个文件 已经添加多个远程服务器
    自动生产jason的工具
    简单的应用可以用storyBoard
    《创业维艰》
    造成死锁的各种情况
  • 原文地址:https://www.cnblogs.com/lqsukida/p/11855962.html
Copyright © 2011-2022 走看看