最近刷题碰到一题有趣的题目,其实难道不是很高,不过一开始想的复杂化了。题目还是比较有意思的。
整个公司的人员结构可以看作是一棵标准的多叉树。树的头节点是公司唯一的老板,除老板外,每个员工都有唯一的直接上级,叶节点是没有任何下属的基层员工,除基层员工外,每个员工都有一个或多个直接下级,另外每个员工都有一个快乐值。
这个公司现在要办 party,你可以决定哪些员工来,哪些员工不来。但是要遵循如下的原则:
1.如果某个员工来了,那么这个员工的所有直接下级都不能来。
2.派对的整体快乐值是所有到场员工快乐值的累加。
3.你的目标是让派对的整体快乐值尽量大。
给定一棵多叉树,请输出派对的最大快乐值。
输入描述:
第一行两个整数 n 和 root,n 表示公司的总人数,root 表示公司的老板。
第二行 n 个整数 happy_i 表示员工 i 的快乐值。
接下来 n - 1 行每行两个整数 u_i 和 v_i 表示 u_i 是 v_i 的直接上级。
输出描述:
输出一个整数表示最大快乐值。
示例1
输入
复制
3 1
5 1 1
1 2
1 3
输出
复制
5
备注:
1 \le n \le 5000001≤n≤500000
0 \le happy_i \le 10000≤happy
i
≤1000
输入保证是一棵树
这题一开始让我懵了一下,因为它不是一颗二叉树,他是多叉树。
其实在类当中放一个子节点的数组就可以了,
然后辅以递归来求解。
这里的本质就是选与不选,犹如打家劫舍,零钱兑换。
我觉得是可以用动态规划的,,但是这里参考评论区我用了记忆化递归。
我尝试过如果不存一下中间的最大值,那么会超时。
递归的过程是这样的,两种选择,选择这一个节点,和不选择这一个节点。
选择就直接加上它的开心值,不选择就将他孩子节点的值都加上。
然后return max(选择之和, 不选择之和),当然为了冗余运算,可以在树类里面使用一个max_happy, 来保存。
也就是说,当max_happy != 0, 就return max_happy
import java.util.*;
public class Main {
public static class TreeNode {
public int val; //快乐值
public List<TreeNode> child;
public TreeNode parent;
public int max_happy;
public TreeNode(int val) {
this.val = val;
this.parent = null;
this.child = new ArrayList<TreeNode>();
this.max_happy = 0;
}
}
public static int dfs(TreeNode root) {
int with_cur = root.val;
int without_cur = 0;
if(root.max_happy != 0)
return root.max_happy;
for(TreeNode num : root.child) {
for(TreeNode ch : num.child) {
with_cur += dfs(ch);
}
}
for(TreeNode num : root.child) {
without_cur += dfs(num);
}
root.max_happy = Math.max(with_cur, without_cur);
return root.max_happy;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int root = in.nextInt();
TreeNode[] company = new TreeNode[n];
for(int i = 0; i < n; i ++) {
int x = in.nextInt();
company[i] = new TreeNode(x);
}
for(int i = 0; i < n - 1; i ++) {
int u_i = in.nextInt();
int v_i = in.nextInt();
u_i -= 1;
v_i -= 1;
company[v_i].parent = company[u_i];
company[u_i].child.add(company[v_i]);
}
int ans = 0;
for(TreeNode num : company) {
if(num.parent == null) {
ans += dfs(num);
}
}
System.out.println(ans);
}
}
此代码通过。