我需要找到一个动态编程'针对以下问题的解决方案:
输入:
(换句话说,树中的一些顶点是蓝色的)
法律解决方案:
顶点子集V' ⊆V是T的顶点覆盖, | V' ∩V(蓝色)| = k 。 (换句话说,封面V'包含k个蓝色顶点)
解决方案价值:
法律解决方案的价值V'是set = | V' |中的顶点数。 为方便起见,我们将定义" un-legal"的价值。解决方案是∞。
我们需要找到的内容:
最小值的解决方案。
(换句话说,最佳解决方案是封面,包含恰好k个蓝色顶点和顶点数的解决方案在集合中最小。)
我需要定义一个典型的子问题。 (就像,如果我知道子树的价值解决方案是什么,我可以用它来找到问题的价值解决方案。)
并建议公式来解决它。
答案 0 :(得分:2)
对我来说,看起来你走在正确的轨道上! 不过,我认为你必须使用一个额外的参数来告诉我们从当前子树的根中获取的顶点有多远。 例如,它可以仅仅是我们是否选择当前顶点的指示,如下所示。
让fun (v, b, p)
成为具有根v
的子树的最佳大小,以便在此子树中,我们选择精确的b
蓝色顶点,如果我们选择顶点,则p = 1
如果我们不这样做,请v
或p = 0
。
答案是fun (r, k, 0)
和fun (r, k, 1)
的最小值:我们想要完整树(v = r
)的答案,其中正好k
个顶点用蓝色覆盖({ {1}}),我们可以选择或不选择根。
现在,我们如何计算呢?
对于叶子,b = k
为fun (v, 0, 0)
,0
为fun (v, t, 1)
,其中1
告诉我们顶点t
是否为蓝色(v
如果是,1
如果没有)。
所有其他组合都是无效的,我们可以通过说相应的值是正无穷大来模拟它:例如,对于叶顶点0
,值v
。
在实现中,无穷大可以是任何大于任何可能答案的值。
对于所有内部顶点,让fun (v, 3, 1) = +infinity
为当前顶点,v
和u
为其子节点。
我们有两个选择:选择或不选择顶点w
。
假设我们选择它。
然后,我们获得v
的值为f (v, b, 1)
(拾取的顶点1
)加上v
的最小值,fun (u, x, q) + fun (w, y, r)
为x + y
如果顶点b
为黑色,或v
如果是蓝色,b - 1
和q
可以是任意的:如果我们选择顶点r
,则边缘v
和v--u
已被我们的顶点封面覆盖。
现在让我们不要选择顶点v--w
。
然后我们获得v
的值只是f (v, b, 0)
的最小值fun (u, x, 1) + fun (w, y, 1)
:如果我们没有选择顶点x + y = b
,则边v
和v--u
和v--w
必须涵盖u
。