动态规划最优解

时间:2015-03-23 19:57:37

标签: algorithm dynamic-programming

一家公司正计划为其员工举办派对。为每位员工分配一个有趣的评级。 员工被组织成一个严格的等级,即一棵根植于总统的树。有一个 但是,在聚会的客人名单上限制:一名员工和他/她的直接主管 (树中的父母)不能同时参加聚会。您希望为该派对准备一份嘉宾名单 最大化客人的有趣评级总和。表明贪婪地选择客人的乐趣 评级,不会起作用。然后,制定动态编程解决方案

我无法理解一些条件,比如总统的乐趣率高于他的后代,以及他的每个主管有多少员工。有人可以帮助我继续这个吗?

2 个答案:

答案 0 :(得分:1)

根据问题的措辞,分层树中分配给某人的有趣评级不一定大于层次结构树中的后代。

然而,即使是这种情况,要看到挑选最好的员工并不是最佳选择,可以考虑一个高度为2的树,其乐趣的根= 10和20个乐趣的孩子= 1。然后,最佳解决方案是跳过贪婪的选择(根)并选择20个孩子。

在任何情况下,通过动态编程,您可以找到最佳解决方案,即使父母可以比他们的后代享有更低的乐趣。对于树中的节点v,让F(v)成为以v为根的子树中可以获得的最大乐趣。然后你选择v,在这种情况下跳过子节点,你看看所有植根于子节点的子树孩子们(在这些子树上获取最大乐趣的总和,并添加到乐趣(v)),或者你跳过v然后你获得最大的乐趣是根据v的孩子们的所有子树的最大乐趣的总和。这给出了线性时间动态规划算法。

答案 1 :(得分:1)

贪婪的例子显示了一个简单的反例。

    1
    |
 1--3--1
    |
    1

贪婪地选择,即首先选择3不会让我们选择任何其他员工。但如果我们不选择3,那么max将是4(全部为1' s)。所以贪婪的方法不起作用。

对于动态编程,我们可以将问题表述为选择给定的子树根。如果我们选择一个节点,则不能选择任何一个节点。但是,如果我们不选择节点,我们可以选择孩子,也可以不选择孩子。

for all v initialize
  c(v,true) = fun(v)
  c(v,false)= 0

使用以下递归来解决问题

weight(v,true)  = for all children sum( weight(ci,false) ) + fun(i)
weight(v,false) = for all children sum( max(weight(ci,false), weight(ci,true)))

根节点的答案为max(weight(v,true),weight(v,false))