标签:roo pre str ini last class val 后续遍历 ret
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 11 class Solution { 12 public: 13 int rob(TreeNode* root) { 14 return back(root)->val; 15 } 16 private: 17 struct DPnode { 18 int val; 19 int lsval; 20 }; 21 DPnode* back(TreeNode* root) { 22 DPnode* dpn = new DPnode; 23 if (!root) { 24 dpn->val = 0; 25 dpn->lsval = 0; 26 return dpn; 27 } 28 DPnode* dpl = back(root->left); 29 DPnode* dpr = back(root->right); 30 int lr = dpl->val + dpr->val; 31 int llr = dpl->lsval + dpr->lsval; 32 if (lr > llr + root->val) { 33 dpn->val = lr; //not select this node 34 }else { 35 dpn->val = llr + root->val; 36 } 37 dpn->lsval = lr; 38 return dpn; 39 } 40 };
一维抢劫问题的DP方程:dp[i] = max{dp[i-1], dp[i-2] + vi};
如果数据结构是二叉树,比较适合从下往上后续遍历
本结点的左右子结点(对应一维的dp[i-1]):dplv,dprv
子结点的子结点(对应一维的dp[i-2]):lastdplv,lastdprv
因为树不好直接访问,每个节点需要保留以上两个值
方程:dpv = max{dplv + dprv, v + lastdplv + lastdprv};
本结点不选,选本结点的左右子树节点dplv + dprv
或者选本结点,并选左右子树节点的左右子结点:v + lastdplv + lastdprv
本结点的子结点dp:lastdpv = dplv + dprv;
标签:roo pre str ini last class val 后续遍历 ret
原文地址:https://www.cnblogs.com/jkserge/p/9318467.html