当前位置: 首页 > 知识库问答 >
问题:

树的最小顶点覆盖:动态规划公式

柳豪
2023-03-14

我试图理解如何将寻找树的最小顶点覆盖的问题表述为一个动态规划问题,但遇到了一些麻烦。对我来说,涉及深度优先搜索的非动态规划公式具有最直观的意义。从本质上讲,这涉及到对叶节点进行DFS,包括最小大小顶点覆盖中的父节点,并重复到根节点。伪代码是这样的:

// DFS based solution
find_minimum_vertex_cover_dfs(root) {
    // leaf nodes aren't in minimum size vertex cover
    if (root == NULL || isLeafNode(root)) {
        return;
    }

    for (each child node of root) {
        find_minimum_vertex_cover_dfs(child node);
        // child isn't in minimum size vertex cover so need to cover edge
        // from current root to child by including current root
        if (!isInMinCover(child node)) {
            include root in minimum vertex cover;
        }
    }
}

我从这里得到的动态规划公式如下:

DynamicVC(root):
    for each child c:
        Best[c][0], Best[c][1] = DynamicVC(c)

    withoutRoot = sum over all c of Best[c][1]
    withRoot = 1 + sum over all c of min(Best[c][0], Best[c][1])

    return (withoutRoot, withRoot)

我想我理解子问题的思想是计算根植于每个顶点的子树的最小大小顶点复盖,包括复盖中的那个顶点,并从复盖中排除那个顶点。我有两个问题:

    null

编辑:当我想的更多的时候,可能让我困惑的是,在这个例子中,递归地在树上做一个DFS是我更熟悉的。我已经做了很多动态规划问题,但这是第一个涉及树/图遍历的问题,在其他问题中,我可以使用一些循环来计算越来越大的子问题。我想我可以通过使用显式堆栈并以这种方式进行树遍历(而不是通过递归)来使动态编程版本更加熟悉。这有道理吗?

共有1个答案

朱祺
2023-03-14

1:没有真正好的理由。它只是工作,所以为什么不使用它。对我来说,你所展示的DP解比递归解更直观。

2:动态规划是关于一个递归解的子问题的记忆。提出一个DP算法通常需要先定义一个递归,然后再给它添加记忆。递归解决方案可以自动转换为DP:只需创建(Subproblemid->result)类型的全局哈希表,并在递归调用开始时检查hashmap是否已经包含给定子问题的结果,如果是,则立即返回它,否则计算它并将其放入hashmap。这种方法通常与您提到的自下而上的方法一样快。

 类似资料:
  • 我需要为以下问题找到一种“动态编程”的解决方案: 完美二叉树,T=(V,E)-(每个节点只有两个子节点,除了叶子) V=V(蓝色)∪ V(黑色)。V(蓝色)∩ V(黑色)=∅. (换句话说,树中的一些顶点是蓝色的) 树根'r'. 整数k 顶点V'V的子集,它是T的顶点覆盖,并且|V'∩V(蓝色)|=k。(换句话说,覆盖V'包含k个蓝色顶点) 合法解V'的值是集合中的顶点数=|V'|。为了方便起见,

  • 我试图找出一种算法来寻找二部图的最小顶点覆盖。 我在考虑一个解决方案,将问题简化为二部图中的最大匹配。众所周知,可以使用从bip创建的networ中的最大流量来找到它。图表 最大匹配M应该决定最小。顶点覆盖C,但我无法处理选择要设置C的顶点。假设bip。图有部分X、Y,作为最大匹配边endpoint的顶点在集合A中,那些不属于B的顶点。 我会说,我应该为M到C中的边选择一个顶点。特别是M中的边e的

  • 我正在复习在寻找两个等长字符串的最长公共子序列的上下文中讨论动态规划的笔记。有问题的算法输出长度(而不是子字符串)。 所以我有两个字符串,说: S=ABAZDC,T=BACBAD 最长的公共子序列是ABAD(子字符串不必是相邻的字母) 算法如下,其中LCS[i,j]表示S[1..i]和T[1..j]的最长公共子序列: 我的笔记声称你可以填写一个表格,其中每个字符串都沿着一个轴写。比如: B A C

  • 问题-你会得到不同面额的硬币和总金额。写一个函数来计算你需要的最少数量的硬币来组成这个数量。那里有无限的硬币供应。 我的方法——我遵循了自上而下的方法,但是使用map stl进行记忆,我得到了TLE。请帮助找出误差和估计时间复杂度。 这是我的密码-

  • 有人可以帮助解决以下问题,使用DP技术。 不需要代码。这个想法应该足够了。 惊奇漫画即将推出一个新的超级英雄,名为跳跃杰克。这位超级英雄的共同创造者是一位数学家,他为角色的力量添加了数学元素。 所以,跳跃杰克最突出的能力之一是跳跃距离。但是,这个超级大国有一定的限制。 杰克只能跳- 到比当前距离小一公里的数字。例如,如果他离目的地12公里,他就不能直接跳到目的地,因为他只能跳到11公里外的地方。

  • 将求解第一个点的第一个圆放置在适当位置。 通过检查这两个点之间的距离是否小于2*r来求解最小圈数中的第二个点。并继续处理所有n个点。我认为是贪婪算法,但它是最优的,线性的吗?