1 solutions
-
0
题面描述
在一个满二叉树结构的网络中,节点上标有年度维护成本的非负整数。给定节点的数量和其对应的成本值,要求通过撤销一些节点来最大化节省的维护成本,但不能同时撤销原本直接相邻的两个节点。需要根据输入的节点信息,输出能够节省的最大维护成本。
思路
这道题是洛谷P1352-没有上司的舞会一题的改版.具体做法是树形.
动态规划题目重点有两个:状态定义,状态转移.
状态定义
我们记为当前以为根节点的子树的最高维护成本,其中第二维度为0表示根节点也被撤销,为1表示根节点未被撤销.
状态转移
我们记为的权值,假设是的左孩子,是的右孩子,那么当我们选择不撤销时,和必须被撤销.因此.
现在我们考虑如果被撤销时该如何选择.
我们发现被撤销后,和都可以被撤销或者不被撤销.因此,按照贪心的思路,我们就判断和被撤销和不被撤销的两种情况哪一个维护成本高.具体就是求和.因此最后的转移方程为$dp[u][1] = max(dp[left][0], dp[left][1]) + max(dp[right][0], dp[right][1])$
思路解析
-
状态定义:
- 我们定义
dp[u][0]
为以节点u
为根的子树中,撤销节点u
时所能获得的最大维护成本。 dp[u][1]
表示不撤销节点u
时所能获得的最大维护成本。
- 我们定义
-
状态转移:
- 对于一个节点
u
,我们需要考虑它的左子节点left
和右子节点right
。 - 不撤销节点
u
:如果我们选择不撤销u
,那么left
和right
必须被撤销,因此: [ dp[u][1] = dp[left][0] + dp[right][0] ] - 撤销节点
u
:如果我们选择撤销u
,那么left
和right
可以被撤销也可以不撤销。我们需要选择使得维护成本最大的方案: [ dp[u][0] = arr[u] + dp[left][0] + dp[right][0] ] 其中 ( arr[u] ) 是节点u
的维护成本。
- 对于一个节点
-
递归遍历:
- 使用深度优先搜索(DFS)来遍历每个节点,计算其状态并填充
dp
数组。
- 使用深度优先搜索(DFS)来遍历每个节点,计算其状态并填充
代码
CPP
python
Java
Go
Js
-
- 1
Information
- ID
- 33
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 8
- Tags
- # Submissions
- 30
- Accepted
- 14
- Uploaded By