题目描述
员工信息的定义如下:
class Employee{
int happy; // 这名员工可以带来的快乐值
std::vector<Employee*> next; // 这名员工有哪些直接下级
};
公司的每个员工都符合 Employee 类的描述。整个公司的人员结构可以看作是一棵标准的、 没有环的多叉树。
树的头节点是公司唯一的老板。除老板之外的每个员工都有唯一的直接上级。
叶节点是没有任何下属的基层员工(subordinates列表为空),除基层员工外,每个员工都有一个或多个直接下级。
这个公司现在要办party,你可以决定哪些员工来,哪些员工不来,规则:
- 如果某个员工来了,那么这个员工的所有直接下级都不能来
- 派对的整体快乐值是所有到场员工快乐值的累加
- 你的目标是让派对的整体快乐值尽量大
给定一棵多叉树的头节点boss,请返回派对的最大快乐值。
class Employee{
public:
int happy; // 这名员工可以带来的快乐值
std::vector<Employee*> next; // 这名员工有哪些直接下级
};
class Solution {
public:
int maxHappy(Employee* boss) {
}
};
题目解析
对于每一个root,它有两种决策:
- 当前节点来,则它的子节点不能来,即:root.heap + max(子节点不来)
- 当前节点不来,则它的子节点可以来也可以不来,即: 0 + max(子节点来,子节点不来)
因此,每次都需要从左树和右树中我们都需要 来,不来 的最大快乐值
递归
class Employee{
public:
int happy; // 这名员工可以带来的快乐值
std::vector<Employee*> nexts; // 这名员工有哪些直接下级
};
class Solution {
struct Info{
public:
int no;
int yes;
Info(int no, int yes) : no(no), yes(yes){
}
};
std::shared_ptr<Info>process(Employee* boss){
if(boss == nullptr){
return std::make_shared<Info>(0, 0);
}
int no = 0;
int yes = boss->happy;
for(auto next : boss->nexts){
auto nextInfo = process(next);
no += std::max(nextInfo->yes, nextInfo->no);
yes += nextInfo->no;
}
return std::make_shared<Info>(no, yes);
}
public:
int maxHappy(Employee* boss) {
if(boss == nullptr){
return 0;
}
auto allInfo = process(boss);
return std::max(allInfo->yes, allInfo->no);
}
};
递归
class Employee{
public:
int happy; // 这名员工可以带来的快乐值
std::vector<Employee*> next; // 这名员工有哪些直接下级
};
class Solution {
// 当前来到的节点叫cur,
// up表示cur的上级是否来,
// 该函数含义:
// 如果up为true,表示在cur上级已经确定来,的情况下,cur整棵树能够提供最大的快乐值是多少?
// 如果up为false,表示在cur上级已经确定不来,的情况下,cur整棵树能够提供最大的快乐值是多少?
int process(Employee* cur, bool up){
if(up){ // 如果cur的上级来的话,cur没得选,只能不来
int ans = 0;
for(auto next : cur->next){
ans += process(next, false);
}
return ans;
}else{ // // 如果cur的上级不来的话,cur可以选,可以来也可以不来
int p1 = cur->happy, p2 = 0;
for(auto next : cur->next){
p1 += process(next, true);
p2 += process(next, false);
}
return std::max(p1, p2);
}
}
public:
int maxHappy(Employee* boss) {
if(boss == nullptr){
return 0;
}
return process(boss, false);
}
};