zoukankan      html  css  js  c++  java
  • 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)

    根据最近做的几道树形dp题总结一下规律。(从这篇往前到洛谷 P1352 )
    这几道题都是在一颗树上,然后要让整棵树的节点或边
    满足一种状态。然后点可以影响到相邻点的这种状态
    然后求最小次数

    那么要从两个维度来设计状态
    第一个维度
    (1)以i为根的树的所有节点都满足这种状态
    (2)以i为根的树的只有i不满足这种状态
    第二个维度
    (1)i这个点取
    (2)i这个点不取

    所以就会有四种状态,不过最近几道题都是直接pass掉了其中一种
    只有三种状态。
    状态设计好了就很好写转移方程了,记住转移的过程中孩子一定
    要都满足状态,这样做下来才可以使得整棵树满足状态。


    然后我们把这个模型套到这道题
    第一个维度
    亮表示以i为根的子树全部节点都亮
    不亮表示以i为根的子树只有i不亮
    第二个维度
    i这个灯泡开或者不开
    所以状态是

    (1)f[i][0] 没开,亮
    (2)f[i][1] 没开,没亮
    (3)f[i][2] 开,亮
    (4)f[i][3] 开,没亮

    这里f[i][3]pass掉,因为你要把没亮变成亮需要根节点按按钮,
    此时跟节点消耗一个操作,而孩子自己又消耗一个操作
    如果是开,亮的话只用消耗孩子一个操作。

    现在写状态转移方程
    u表示根节点,v表示孩子
    f[u][2] = sum(f[v][1])
    这时跟节点一开就都亮了(f[u][2]一开始会初始化为1)

    f[u][0] = sum(min(f[v][0], f[v][2]))

    f[u][1] = sum(min(f[v][0], f[v][2]))

    这里有个奇偶数的问题,令sum = sum(min(f[v][0], f[v][2]))

    不仅要算出sum
    然后还要算出以最小花费把其中一个min换成另外一个操作的值,即sum + mint
    假设f[v][2]是奇数,意味着当前是亮的,所以f[u][1] = sum + mint,f[u][0] = sum   
    如果是偶数,就反过来,f[u][1] = sum,f[u][0] = sum + mint 

    这里有小细节,到叶子结点的时候,f[u][0]是不可能的(不考虑父亲)
    那么这时按照程序f[u][0]会等于无穷大,所以相当于不可能
     

  • 相关阅读:
    指针函数与函数指针
    多版本python共存
    【转】手把手教你用Strace诊断问题
    gearman安装问题总结
    【转】nginx+memcached构建页面缓存应用
    【摘自张宴的"实战:Nginx"】http auth baseic模块(打开页面需要密码验证)
    【转】nginx的模块变量(HTTP核心模块变量)
    【摘自张宴的"实战:Nginx"】try_files指令
    nginx显示目录下面的文件
    【摘自张宴的"实战:Nginx"】nginx配置
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819391.html
Copyright © 2011-2022 走看看