没有上司的舞会
没有上司的舞会
题目描述
某大学有 $n$ 个职员,编号为 $1\ldots n$。
他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。
现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 $r_i$,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。
所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。
输入格式
输入的第一行是一个整数 $n$。
第 $2$ 到第 $(n + 1)$ 行,每行一个整数,第 $(i+1)$ 行的整数表示 $i$ 号职员的快乐指数 $r_i$。
第 $(n + 2)$ 到第 $2n$ 行,每行输入一对整数 $l, k$,代表 $k$ 是 $l$ 的直接上司。
输出格式
输出一行一个整数代表最大的快乐指数。
样例 #1
样例输入 #1
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
样例输出 #1
5
提示
数据规模与约定
对于 $100\%$ 的数据,保证 $1\leq n \leq 6 \times 10^3$,$-128 \leq r_i\leq 127$,$1 \leq l, k \leq n$,且给出的关系一定是一棵树。
Analysis
本题实质上是一个树形dp的问题。设 f[i][j] 表示选择指定节点i后,获得的最大价值,其中j分为两种情况,选
或不选
,对于我们来说,只需要枚举所有可能的情况,求得最大值即可, 具体情况如下:
-
当前节点
\[f[i][1] = v[i] + \sum_{j=1}^{k} f[j][0] \hspace{1cm} j \in g[i]\;,\; k ==len(g[i])\]i
选择, 则价值为: -
当前节点
\[f[i][0] = \sum_{j=1}^{k} (min(f[j][0], f[j][1])) \hspace{1cm} j \in g[i]\;,\; k ==len(g[i])\]i
不选择, 则价值为 : -
最后整棵树的最大价值为:
\[maxval = max(f[root][0], f[root][1])\]
Solutions
1. Monotanic-Stack
from collections import defaultdict
import sys
sys.setrecursionlimit(10**9)
n = int(input())
happiness = [int(input()) for _ in range(n)]
boss = [list(map(int, input().split()))for _ in range(n-1)]
graph = defaultdict(list)
in_degree = [0] * n
for u, v in boss:
graph[v].append(u)
in_degree[u - 1] += 1
def dfs(root):
choose = happiness[root - 1]
not_choose = 0
for child in graph[root]:
child_not_choose, child_choose = dfs(child)
choose += child_not_choose
not_choose += max(child_not_choose, child_choose)
return [not_choose, choose]
for i, num in enumerate(in_degree):
if num == 0:
root = i + 1
ans= max(dfs(root))
print(ans)
Input:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
output:
5
Complexity
- Time complexity: ( O(2^n) ), where ( n ) is the length of the array.
- Space complexity: ( O(2^n) ), where ( n) is the length of the array.
Comments