Java DP with explanation
\nclass Solution {\n    // using DFS and backtracking; bottom to top\n    // at certain point/node, this is how we determine the max\n    // There are a couple 
```\nclass Solution {\n    // using DFS and backtracking; bottom to top\n    // at certain point/node, this is how we determine the max\n    // There are a couple of cases at this node \n    // 1. if we consider to rob this node: max is current root.val + the value get from \n    // robbing both its grandchildren \n    // 2. if we consider not to rob: max is the sum of both its left child sum and its right \n    // sum if exists \n    // finally, we take the max and return and of course store the result into hashmap for \n    // future use\n    \n    public int DFS(TreeNode root, HashMap<TreeNode, Integer>map){\n        if(root == null) return 0;\n        \n        // if this root has been visited and the max has been calculated, return immediately\n        if(map.containsKey(root)) return map.get(root);\n        \n        int result = 0;\n        // say we rob the current root, we will also rob its both grandchildren\n        // below is to rob its left child\'s both children\n        if(root.left != null)\n            result += DFS(root.left.left, map) + DFS(root.left.right, map); \n        // below is to rob its right child\'s both children\n        if(root.right != null)\n            result += DFS(root.right.left, map) + DFS(root.right.right, map);\n        \n        // the sum we get from result will be compared to just robbing its left and right child \n        result = Math.max(result + root.val, DFS(root.left, map)+DFS(root.right, map));\n        map.put(root, result);\n        return result;\n    \n    }\n    public int rob(TreeNode root) {\n        return DFS(root, new HashMap<TreeNode, Integer>());\n    }\n}\n```
[]