树长度有限的最大子树总和

时间:2016-06-05 12:42:13

标签: graph-algorithm

我有一个树形结构。 任务是找到路径节点的最大总和/重量,但我只能移动 n次。多数民众赞成,但“向上”/“退回”不需要任何费用。 我怎么能做到这一点?

下面是我的代码,但问题是每个节点只能访问一次,所以它不起作用。

int mSum(Node* node, int mvLeft) {
    if (node == nullptr) { return 0; }
    if (mvLeft == 0) { return node->value; }
    mvLeft--;
    int sum = max(mSum(node->left, mvLeft), mSum(node->right, mvLeft));
    return node->value + max(sum, mSum(node->parent, mvLeft + 1));
}

这是示例图。节点上的数字代表了获取它的成本。除了“返回”之外,每个节点只能访问一次 n步长限制为3 ,我们也计算进入图表,因此正确的结果是21,因为:2-> 8-> 11。 如果我们将限制4个步骤,则结果将是31:2-> 10-> 8-> 11 Visualization of the example tree
我的朋友试图用DFS做到这一点,对吗?什么是最好的算法?

1 个答案:

答案 0 :(得分:0)

好的答案是同时采用多条路线。 我的意思是我们可以使用2长度限制:

  • 2 left 0 right
  • 1 left 1 right
  • 0 left 2 right

工作,但有点慢,代码:) 它的工作时间是28s,而其他解决方案可以使用2s(10个未知的测试)

int mSum(Node* node, int mvLeft) {
    mvLeft--;
    if (mvLeft < 0) {
        return 0;
    }
    else if (mvLeft == 0) {
        return node->value;
    }

    if (node->left != nullptr && node->right != nullptr) {
        int max = 0;
        for (int i = 0; i <= mvLeft; i++) {
            max = Max(max, mSum(node->left, i) + mSum(node->right, mvLeft - i));
        }
        return max + node->value;
    }
    else if (node->left != nullptr) {
        return mSum(node->left, mvLeft) + node->value;
    }
    else if (node->right != nullptr) {
        return mSum(node->right, mvLeft) + node->value;
    }
    return node->value;
}