题目

树上DP。
对于树的一个节点开始,它的子树可以盗取的最大金额由它的两个状态组成:
- 该点被盗,记为f(i)
- 该点不被盗,记为g(i)
则
f
f
f 和
g
g
g 由其左右节点的状态决定:
f
(
i
)
=
n
o
d
e
.
v
a
l
+
g
(
l
)
+
g
(
r
)
f(i)=node.val+g(l)+g(r)
f(i)=node.val+g(l)+g(r)
g
(
i
)
=
m
a
x
g(i)=max
g(i)=max
{
f
(
l
)
,
g
(
l
)
}
+
m
a
x
\lbrace f(l),g(l)\rbrace+max
{f(l),g(l)}+max
{
f
(
r
)
,
g
(
r
)
}
\lbrace f(r),g(r)\rbrace
{f(r),g(r)}
最后 f ( r o o t ) f(root) f(root)和 g ( r o o t ) g(root) g(root)的最大值就是最后答案。
由递推式可以看出,应该是从底向上就是递推,左右根得出结论,因此采用后序遍历方法,逐步推出结果。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<TreeNode,Integer> f=new HashMap<TreeNode,Integer>();
Map<TreeNode,Integer> g=new HashMap<TreeNode,Integer>();
public int rob(TreeNode root) {
dfs(root);
return Math.max(f.getOrDefault(root,0),g.getOrDefault(root,0));
}
private void dfs(TreeNode node){
if(node==null) return;
dfs(node.left);
dfs(node.right);
f.put(node,node.val+g.getOrDefault(node.left,0)+g.getOrDefault(node.right,0));
g.put(node,Math.max(f.getOrDefault(node.left,0),g.getOrDefault(node.left,0))+Math.max(f.getOrDefault(node.right,0),g.getOrDefault(node.right,0)));
}
}

本文探讨了树形结构上的动态规划问题,即在树状结构中如何选择节点进行盗窃以获得最大收益,同时确保相邻节点不会同时被选中。通过定义节点被盗和未被盗两种状态,利用递归后序遍历的方法,自底向上地计算每个节点的最优解,最终得到树根节点的最大收益。
341

被折叠的 条评论
为什么被折叠?



