我得到一棵树,我必须删除节点以使用k叶子转换树。每个节点都有一个与之关联的权重。删除节点将花费相关的权重。我想尽量降低成本。
以下是问题的链接 - :http://www.iarcs.org.in/inoi/online-study-material/topics/dp-trees.php
我无法想象解决方案。我需要一些帮助。如果有人能够以广泛的方式解释或提供一些文档会有所帮助。
答案 0 :(得分:0)
以下是如何做到这一点的想法(您可能需要修改并添加一些内容才能使其正常工作) -
如链接中所述,我们将使用二维数组(例如dp)来存储我们的部分答案并使用它们来查找所需的答案。其次,dp[v][k]
将表示使用根节点(子树或主树) v ,我们需要完全 k 叶节点。
基本案例 -
对于任何叶节点lv -
//Case 1 - only one leaf is required so we dont need to delete any node
dp[lv][1] = 0
//Case 2 - more than 1 leaf node required which is not possible
dp[lv][k] = INT_MAX
对于任何节点v -
//As no leaf is required we delete all nodes
dp[v][0] = sum of weights of all nodes in subtree with v(including weight of v)
DP的力学 -
现在假设我们目前处于节点 v ,我们需要在此节点的子树中包含 k 叶子。让我们先写一下如何编写代码,然后我将解释它是如何工作的。
for(int i=0;i<=k;i++)
dp[v][k] = min( dp[v][k], dp[left-child][i] + dp[right-child][k-i];
此处left-child
和right-child
是 v 的左右节点。
对于每个叶节点,有两件事是可能的,即它可以是左子树或右子树。所以,我正在迭代所有这些状态,从不包含叶子节点的left-suubtree开始到包含所有叶子节点的left-subtree,以及右子树的相同。最后,存储从dp[v][k]
迭代中找到的最小值。