Problem
There exists an undirected tree rooted at node 0 with n nodes labeled from 0 to n - 1. You are given a 2D integer array edges of length n - 1, where edges[i] = [aᵢ, bᵢ] indicates that there is an edge between nodes aᵢ and bᵢ in the tree. You are also given a 0-indexed array coins of size n where coins[i] indicates the number of coins in the vertex i, and an integer k.
Starting from the root, you have to collect all the coins such that the coins at a node can only be collected if the coins of its ancestors have been already collected.
Coins at nodeᵢ can be collected in one of the following ways:
- Collect all the coins, but you will get
coins[i] - kpoints. Ifcoins[i] - kis negative then you will loseabs(coins[i] - k)points. - Collect all the coins, but you will get
floor(coins[i] / 2)points. If this way is used, then for all thenodeⱼpresent in the subtree ofnodeᵢ,coins[j]will get reduced tofloor(coins[j] / 2).
Return the maximum points you can get after collecting the coins from all the tree nodes.
https://leetcode.cn/problems/maximum-points-after-collecting-coins-from-all-nodes/
Example 1:

Input:
edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
Output:11
Explanation:
Collect all the coins from node 0 using the first way. Total points= 10 - 5 = 5.
Collect all the coins from node 1 using the first way. Total points= 5 + (10 - 5) = 10.
Collect all the coins from node 2 using the second way so coins left at node 3 will befloor(3 / 2) = 1. Total points= 10 + floor(3 / 2) = 11.
Collect all the coins from node 3 using the second way. Total points= 11 + floor(1 / 2) = 11.
It can be shown that the maximum points we can get after collecting coins from all the nodes is 11.
Example 2:

Input:
edges = [[0,1],[0,2]], coins = [8,4,4], k = 0
Output:16
Explanation:
Coins will be collected from all the nodes using the first way. Therefore, total points= (8 - 0) + (4 - 0) + (4 - 0) = 16.
Constraints:
n == coins.length2 <= n <= 10⁵0 <= coins[i] <= 10⁴edges.length == n - 10 <= edges[i][0], edges[i][1] < n0 <= k <= 10⁴
Test Cases
1 | class Solution: |
1 | import pytest |
Thoughts
定义 dp(u, i) 表示以 u 为根节点的子树,其祖先节点已经执行过 i 次方案二,所能得到的最大 points。显然(其中 v 是 u 的子节点):
即对节点 u 执行方案一或者方案二,二者取大。
考虑到 coins[u] 最大值为 10⁴,当 i ≥ 14 时,coins[u] 就一定为 0 了,所以 i 可以只取 0 到 13。另外 i 也不会超过树的高度,但本题中树的高度可以达到 O(n) 量级。
用后序遍历树,处理完所有的子节点后,汇总出中间节点的结果。
这里直接用递归实现。也可以用栈加循环来模拟递归(类似于 3249. Count the Number of Good Nodes),但不一定比直接递归快。
时间复杂度 O(n * log m),其中 m 是 10⁴ 或者 coins 中的最大值,空间复杂度 O(n * log m) 或者 O(h * log m),其中 h 是树的高度(平均情况下 h ≈ O(log n))。
Code
1 | class Solution: |