派对最大快乐值问题
作者:Grey
原文地址:
题目描述
员工信息的定义如下:
public static class Employee { public int happy; // 这名员工可以带来的快乐值 public List<Employee> subordinates; // 这名员工有哪些直接下级 public Employee(int h) { happy = h; subordinates = new ArrayList<>(); } }
公司的每个员工都符合 Employee 类的描述。整个公司的人员结构可以看作是一棵标准的、没有环的多叉树。树的头节点是公司唯一的老板。除老板之外的每个员工都有唯一的直接上级。
叶节点是没有任何下属的基层员工(subordinates列表为空),除基层员工外,每个员工都有一个或多个直接下级。这个公司现在要办 party,你可以决定哪些员工来,哪些员工不来,
规则:
1.如果某个员工来了,那么这个员工的所有直接下级都不能来
2.派对的整体快乐值是所有到场员工快乐值的累加
3.你的目标是让派对的整体快乐值尽量大 给定一棵多叉树的头节点 boss,请返回派对的最大快乐值。
题目链接: 没有上司的舞会
本题可以用二叉树的递归套路方法来解,
定义如下数据结构
public static class Info { public int yes; public int no; public Info(int yes, int no) { this.yes = yes; this.no = no; } }
其中:
yes
变量表示当前员工来的话,最大快乐值是多少。
no
变量表示当前不来的话,最大快乐值是多少。
定义递归函数
public static Info p(Employee boss){}
表示当前员工来或者不来的最大快乐值是多少。
接下来是整理可能性
-
当前员工参加,下属员工都不可以参加
-
当前员工不参加,下属员工可以参加也可以不参加
依据上述可能性,递归函数实现如下(核心代码见注释说明)
public static Info p(Employee boss) { if (boss.subordinates == null || boss.subordinates.isEmpty()) { return new Info(boss.happy, 0); } List<Employee> subordinates = boss.subordinates; int yes = boss.happy; int no = 0; for (Employee e : subordinates) { Info info = p(e); // boss参加了,下属可以不参加 yes += info.no; // boss没有参加,下属可以参加也可以不参加 no += Math.max(info.yes, info.no); } return new Info(yes, no); }
主函数直接调用
Info info = p(boss); // 当前员工来或者不来的最大值 return Math.max(info.yes, info.no);
完整代码见
import java.util.*; public class Main { public static class Employee { public int happy; public List<Employee> subordinates; public Employee(int happy) { this.happy = happy; this.subordinates = new ArrayList<>(); } } public static class Info { public int yes; public int no; public Info(int yes, int no) { this.yes = yes; this.no = no; } } public static int maxHappy(Employee boss) { if (boss == null) { return 0; } Info info = p(boss); return Math.max(info.yes, info.no); } public static Info p(Employee boss) { if (boss.subordinates == null || boss.subordinates.isEmpty()) { return new Info(boss.happy, 0); } List<Employee> subordinates = boss.subordinates; int yes = boss.happy; int no = 0; for (Employee e : subordinates) { Info info = p(e); // boss参加了,下属可以不参加 yes += info.no; // boss没有参加,下属可以参加也可以不参加 no += Math.max(info.yes, info.no); } return new Info(yes, no); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int count = sc.nextInt(); Map<Integer, Employee> map = new HashMap<>(); List<Integer> tmp = new LinkedList<>(); for (int i = 1; i <= count; i++) { int happy = sc.nextInt(); map.put(i, new Employee(happy)); tmp.add(i); } Set<Integer> notBoss = new HashSet<>(); for (int i = 1; i <= count; i++) { if (i != count) { int child = sc.nextInt(); int father = sc.nextInt(); notBoss.add(child); Employee f = map.get(father); Employee c = map.get(child); f.subordinates.add(c); } } int bossIndex = 0; for (Integer it : tmp) { if (!notBoss.contains(it)) { bossIndex = it; break; } } Employee boss = map.get(bossIndex); System.out.println(maxHappy(boss)); sc.close(); } }