树型dp

[Algo] 树型dp

1. 二叉搜索子树的最大键值和

// 1. 二叉搜索子树的最大键值和
// https://leetcode.cn/problems/maximum-sum-bst-in-binary-tree/
struct Info1 {
    int maxSum;
    int maxVal;
    int minVal;
    bool isBST;
    int sum;
    Info1(int a, int b, int c, bool d, int e) : maxSum(a), maxVal(b), minVal(c), isBST(d), sum(e) {}
};
Info1 func1(TreeNode* root) {
    if (root == nullptr) return Info1(0, INT32_MIN, INT32_MAX, true, 0);
    Info1 infol = func1(root->left);
    Info1 infor = func1(root->right);
    int maxVal = max(max(infol.maxVal, infor.maxVal), root->val);
    int minVal = min(min(infol.minVal, infor.minVal), root->val);
    bool isBST = infol.isBST & infor.isBST & infol.maxVal < root->val & root->val < infor.minVal;
    int sum = infol.sum + infor.sum + root->val;
    int maxSum = max(infol.maxSum, infor.maxSum);
    if (isBST) maxSum = max(maxSum, sum);
    return Info1(maxSum, maxVal, minVal, isBST, sum);
}
int maxSumBST(TreeNode* root) {
    return func1(root).maxSum;
}

2. 在二叉树中分配硬币

// 2. 在二叉树中分配硬币
// https://leetcode.cn/problems/distribute-coins-in-binary-tree/description/
struct Info2 {
    int move;
    int cnt;
    int sum;
    Info2(int a, int b, int c) : move(a), cnt(b), sum(c) {}
};
Info2 func2(TreeNode* root) {
    if (root == nullptr) return Info2(0, 0, 0);
    Info2 infol = func2(root->left);
    Info2 infor = func2(root->right);
    int cnt = infol.cnt + infor.cnt + 1;
    int sum = infol.sum + infor.sum + root->val;
    int move = infol.move + infor.move + abs(infol.cnt - infol.sum) + abs(infor.cnt - infor.sum);
    return Info2(move, cnt, sum);
}
int distributeCoins(TreeNode* root) {
    return func2(root).move;
}

3. 监控二叉树

// 3. 监控二叉树
// https://leetcode.cn/problems/binary-tree-cameras/
int ans = 0;
// 递归含义
// 假设x上方一定有父亲的情况下,这个假设很重要
// x为头的整棵树,最终想都覆盖,
// 并且想使用最少的摄像头,x应该是什么样的状态
// 返回值含义
// 0: x是无覆盖的状态,x下方的节点都已经被覆盖
// 1: x是覆盖状态,x上没摄像头,x下方的节点都已经被覆盖
// 2: x是覆盖状态,x上有摄像头,x下方的节点都已经被覆盖
int func3(TreeNode* root) {
    if (root == nullptr) return 1;
    int retl = func3(root->left);
    int retr = func3(root->right);
    if (retl == 0 || retr == 0) 
    {
        ans++;
        return 2;
    }
    else if (retl == 1 && retr == 1) return 0;
    else return 1;
}
int minCameraCover(TreeNode* root) {
    if (func3(root) == 0) ans++;
    return ans;
}

4. 路径总和 III

// 4. 路径总和 III
// https://leetcode.cn/problems/path-sum-iii/description/
int ans = 0;
void func4(TreeNode* root, int targetSum, long sum, unordered_map<long, int> &presum) {
    if (root == nullptr) return;
    sum += root->val;
    ans += presum[sum - targetSum];
    presum[sum]++;
    func4(root->left, targetSum, sum, presum);
    func4(root->right, targetSum, sum, presum);
    presum[sum]--;
}
int pathSum(TreeNode* root, int targetSum) {
    unordered_map<long, int> presum;
    presum[0] = 1;
    func4(root, targetSum, 0, presum);
    return ans;
}
posted @ 2025-03-22 17:01  yaoguyuan  阅读(6)  评论(0)    收藏  举报