员工信息的定义如下:

Class Employee{

  public int happy; //快乐值

  public List<Employee> subordinates; //该员工的直接下属

}

公司的每个员工都符合上述类的描述。整个公司的人员结构都可看成是一棵标准的、没有环的多叉树。树的头结点是整个公司唯一的老板,除老板之外的员工都有唯一的直接上级。叶子结点是没有任何下属的基层员工(subordinates列表为空),除基层员工外,每个员工都有一个或多个直接下级。

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

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

2.派对的整体快乐值是所有到场员工全部快乐值的累加。

3.你的目标是让派对的整体快乐值尽可能地大。

给定一棵多叉树的头结点boss,请返回派对的最大快乐值。

 

如何分析这个问题?我们还是可以采取递归的方式。对于任意一个员工都有两种可能性——来或不来。如果来,那么该员工的所有直接下属都不能来。但是他下属的下属还是可以来的。因此,对应于该员工来的情况下,我们可以计算出一个他的下属不来时的快乐值;如果该员工不来,那么他的所有直接下属都可以来,当然也可以选择不来,这种情况下,我们就需要在他所有下属来与不来之间选择出一个最大值。计算完毕之后,再递归地进行这个过程。

我们先来看看核心方法:

 

 1 private static Info process(Employee node) {
 2         if (node.subordinates.isEmpty()) {
 3             return new Info(node.happy, 0);
 4         }
 5         int come = node.happy; //该员工来的情况下,整棵树的最大收益
 6         int go = 0; //该员工不来的情况下,整棵树的最大收益
 7         for (Employee next : node.subordinates) {
 8             Info nextInfo = process(next);
 9             go += Math.max(nextInfo.comeMaxHappy, nextInfo.goMaxHappy);
10             come += nextInfo.goMaxHappy;
11         }
12         return new Info(come, go);
13     }

 

这是一个递归函数,因此第一步就是设置递归结束条件。当递归到基层员工时,就该结束了。对于基层员工,他若来,快乐值就是happy;若不来,就是0.直接把这个对象返回出去。其次,我们设置若来时的快乐值come和不来时的快乐值go.然后遍历当前员工的所有直接下属。我们取得来时的快乐值和不来时的快乐值并进行累加。最后创建一个对象并返回出去。

接下来是提供给外界的方法:

1 public static int maxHappy(Employee boss) {
2         Info headInfo = process(boss);
3         return Math.max(headInfo.comeMaxHappy, headInfo.goMaxHappy);
4     }

显然,我们只需知道来和不来二者之间谁最大就行了。

测试代码如下:

 1 import java.util.ArrayList;
 2 
 3 public class MaxHappy {
 4     private static class Employee {
 5         public int happy;
 6         //员工的所有直接下属员工,若员工为基层员工,则该列表为空
 7         public ArrayList<Employee> subordinates;
 8         public Employee(int happy) {
 9             this.happy = happy;
10             subordinates = new ArrayList<>();
11         }
12     }
13 
14     private static class Info {
15         public int comeMaxHappy; //来的最大快乐值
16         public int goMaxHappy; //不来的最大快乐值
17 
18         public Info(int comeMaxHappy, int goMaxHappy) {
19             this.comeMaxHappy = comeMaxHappy;
20             this.goMaxHappy = goMaxHappy;
21         }
22     }
23 
24     private static Info process(Employee node) {
25         if (node.subordinates.isEmpty()) {
26             return new Info(node.happy, 0);
27         }
28         int come = node.happy; //该员工来的情况下,整棵树的最大收益
29         int go = 0; //该员工不来的情况下,整棵树的最大收益
30         for (Employee next : node.subordinates) {
31             Info nextInfo = process(next);
32             go += Math.max(nextInfo.comeMaxHappy, nextInfo.goMaxHappy);
33             come += nextInfo.goMaxHappy;
34         }
35         return new Info(come, go);
36     }
37 
38     public static int maxHappy(Employee boss) {
39         Info headInfo = process(boss);
40         return Math.max(headInfo.comeMaxHappy, headInfo.goMaxHappy);
41     }
42 
43     public static void main(String[] args) {
44         Employee employee46 = new Employee(46);
45         Employee employee12 = new Employee(12);
46         Employee employee30 = new Employee(30);
47         Employee employee1 = new Employee(1);
48         Employee employee3 = new Employee(3);
49         Employee employee7 = new Employee(7);
50         Employee employee90 = new Employee(90);
51         Employee employee40 = new Employee(40);
52         Employee employee25 = new Employee(25);
53         Employee employee8 = new Employee(8);
54         employee8.subordinates.add(employee25);
55         employee8.subordinates.add(employee40);
56         employee40.subordinates.add(employee1);
57         employee40.subordinates.add(employee3);
58         employee40.subordinates.add(employee7);
59         employee25.subordinates.add(employee90);
60         employee7.subordinates.add(employee12);
61         employee7.subordinates.add(employee30);
62         employee1.subordinates.add(employee46);
63         int maxHappyValue = maxHappy(employee8);
64         System.out.println(maxHappyValue);
65     }
66 }

派对的最大快乐值_结点