员工信息的定义如下:
Class Employee{
public int happy; //快乐值
public List<Employee> subordinates; //该员工的直接下属
}
公司的每个员工都符合上述类的描述。整个公司的人员结构都可看成是一棵标准的、没有环的多叉树。树的头结点是整个公司唯一的老板,除老板之外的员工都有唯一的直接上级。叶子结点是没有任何下属的基层员工(subordinates列表为空),除基层员工外,每个员工都有一个或多个直接下级。
这个公司现在要办party,你可以决定哪些员工来,哪些员工不来。但要遵循如下规则:
1.如果某个员工来了,那么这个员工的所有直接下级都不能来。
2.派对的整体快乐值是所有到场员工全部快乐值的累加。
3.你的目标是让派对的整体快乐值尽可能地大。
给定一棵多叉树的头结点boss,请返回派对的最大快乐值。
1、解决方案
1.1、思路:
如何分析这个问题?我们还是可以采取递归的方式。对于任意一个员工都有两种可能性——来或不来。如果来,那么该员工的所有直接下属都不能来。但是他下属的下属还是可以来的。因此,对应于该员工来的情况下,我们可以计算出一个他的下属不来时的快乐值;如果该员工不来,那么他的所有直接下属都可以来,当然也可以选择不来,这种情况下,我们就需要在他所有下属来与不来之间选择出一个最大值。计算完毕之后,再递归地进行这个过程。
1.2、代码:
public static int maxHappy2(Employee boss) {
if (boss == null) {
return 0;
}
Info all = process2(boss);
return Math.max(all.yes, all.no);
}
public static class Info {
//代表该员工在来的时候,最大快乐值是多少
public int yes;
//代表该员工在不来的时候,最大快乐值是多少
public int no;
public Info(int y, int n) {
yes = y;
no = n;
}
}
public static Info process2(Employee x) {
if (x.nexts.isEmpty()) {
//该员工没有直接下属的时候
return new Info(x.happy, 0);
}
//该员工来,其直接下属一定不能来
int yes = x.happy;
//该员工不来,其直接下属有可能来,也有可能不来(取来与不来时候最大的那个快乐值)
int no = 0;
for (Employee next : x.nexts) {
Info nextInfo = process2(next);
yes += nextInfo.no;
no += Math.max(nextInfo.yes, nextInfo.no);
}
return new Info(yes, no);
}