树型DP

117 阅读2分钟

1.树型DP步骤:

    1.列出以X为头节点的树中,答案有哪些可能性
    2.根据所有的可能性,分析出需要的信息
    3.合并第二部的信息,对左树和右树提出同样的要求,写出信息结构
    4.设计递归函数,递归函数是处理以X为头节点的树所有情况下的答案。设计basecase,默认得到左子树和右子树的全部信息,并对这些信息做整合,返回第三部的信息结构。       
    

2.树型DP经典问题:

(1) 二叉树中树中最大距离问题:设计一个函数,返回树中距离最大的两个节点之间的距离

public  int maxDistance(TreeNode root){
    return maxDistance1(root).maxDistance;
}

public class Info{
    int maxDistance;
    int height;

    public Info(int maxDistance, int height) {
        this.maxDistance = maxDistance;
        this.height = height;
    }
}
public  Info maxDistance1(TreeNode node){
    if(node==null) return new Info(0,0);
    Info left = maxDistance1(node.left);
    Info right = maxDistance1(node.right);
    int height = Math.max(left.height,right.height)+1;
    int maxDistance = Math.max(Math.max(left.maxDistance,right.maxDistance), left.height+right.height+1);
    return new Info(maxDistance,height);
}

(2) 员工的快乐值问题:

员工信息定义如下:

class Employee{
        public int happy; //这名员工带来的快乐值
        List<Employee> subordinates; //这名员工有哪些直属下级
    }
    
    
公司的每个员工都符合Employee类的描述。整个公司人员结构可以看作是一颗标准的,没有环的多叉树。树的头节点是公司的唯一的老板,除老板外,每个员工都有唯一的直接上级。叶节点是没有任何下属的基层员工,除基层员工外,每个员工都有一个或多个直接下级

这个公司现在要办party,你可以决定那些员工来,哪些员工不来,但是要遵循如下规则:

1、如果某个员工来了,那么这个员工的所有直接下级都不能来

2、派对的整体快乐值是所有到场员工快乐值的累加

3、你的目标是让派对的整体快乐值最大

给定一个头节点boss,请返回派对的最大快乐值

要求:如果以boss为头节点的整棵树有N个节点,请做到时间复杂度为O(N)
class Employee{
    public int happy; //这名员工带来的快乐值
    List<Employee> subordinates; //这名员工有哪些直属下级
}
public int maxHappy(Employee boss){
    return Math.max(maxHappy1(boss).present,maxHappy1(boss).unpresent);
}
public class Info1{
    int present;    //以X为头节点的树,X参与产生的最大快乐值
    int unpresent;  //以X为头节点的树,X不参与产生的最大快乐值

    public Info1(int present, int unpresent) {
        this.present = present;
        this.unpresent = unpresent;
    }
}

public Info1 maxHappy1(Employee employee){
    if(employee==null) return new Info1(0,0);
    int present = employee.happy;
    int unpresent = 0;
    for (Employee sub : employee.subordinates) {
        Info1 subres = maxHappy1(sub);
        present += subres.unpresent;
        unpresent += Math.max(subres.present,subres.unpresent);
    }
    return new Info1(present,unpresent);
}