zoukankan      html  css  js  c++  java
  • 树型动态规划练习总结

    类型一、多叉树转二叉树进行资源分配

    例如:

    * 例1. 选课:每门课可能有一门先选课,即某些课必须在另外的某节课被选之后才能选,每门课能得的学分不同,求最大学分。

    * 例2. 通向自由的钥匙:可以从一个房间通向另外多个房间,通过每个房间所需的花费不同,得到的价值也不同,用最小花费获得最大价值。

    这种题目的特点是需要在多叉树上进行资源的分配,对不同的子树分配不同的资源,以求最大价值。可以直接在多叉树上用背包的方式求解,但是更常用的方法是用左孩子右兄弟表示法转化为二叉树。

    转化之后的通用状态转移方程:

    用 f(i,j) 表示将总量为 j 的资源分配给以 i 为根节点的子树,则

    f(i, j) = max{ f(i.left, k) + f(i.right, j-cost(i)-k) + value(i), f(i.right, j) },其中 k∈(0, j-cost(i))

    解释一下上面的方程。对于每个节点 i 都有两种决策:

    1. 在节点 i 消耗资源并获得相应价值,然后在节点 i 的子节点和兄弟节点中进行决策;

    2. 忽略节点 i ,在 i 的兄弟节点(i.right)中进行决策。

    以上两道例题的状态转移方程写法都与这种通用写法类似。

    类型二、一个节点的不同状态

    (这种类型不知道怎么叫)

    例如:

    * 例1. 警卫安排:在一个节点上安排警卫可以保证与其相邻的节点的安全,每个节点安排警卫的代价不同,在一棵树上用最小代价保证整棵树的安全。

    * 例2. 没有上司的晚会:职员和他的直接上司不会同时出现在晚会,每个职员在晚会上的快乐程度不同,求晚会的最大快乐程度。

    这种题目的特点是每个节点有各自不同的状态,如警卫安排中每个节点有三种状态:1. 自己设有警卫;2. 父节点设有警卫;3. 子节点设有警卫。例2中每个节点(职员)有两种状态:1. 参加;2. 不参加。

    对每个节点的每个状态进行转移即可。

    如例2:

    用 f(i, 0) 表示 i 不参加晚会,用 f(i, 1) 表示 i 参加晚会,则

    f(i, 0) = sum{ max{ f(j, 0), f(j, 1) } }

    f(i, 1) = sum{ max{ f(j, 0) } }

    (j 是 i 的子节点)

    解释一下上面的两个方程:

    当 i 参加晚会时,i 的下属必然不参加晚会;

    当 i 不参加晚会时,i 的下属可以参加晚会也可以不参加晚会。

    例1类似。

    类型三、二叉树上的资源分配

    是类型一的简化版,题目的模型即二叉树,不用进行转换就可以直接求解。

  • 相关阅读:
    转载-python生成sjf
    111111111111
    【MySQL】使用硬链接的方式删除大表
    【Python】公共类-获取MySQL数据
    【Python】公共类-logger
    文件IO --- sync、fsync、fdatesync
    【Mongo】安装Mongo并配置副本集
    【MySQL】InnoDB 内存管理机制 --- Buffer Pool
    【MySQL】redo log --- 刷入磁盘过程
    Linux 系统的安装
  • 原文地址:https://www.cnblogs.com/lsdsjy/p/3897485.html
Copyright © 2011-2022 走看看