Loading

贪心

区间

Exchange Argument

考虑如下问题:有一些元素,你需要按某种顺序对它们进行操作,使得收益最大。

通过交换相邻两项,得出一个元素排在另一个前面更优的条件(需要具有传递性),然后按这个条件排序即可。

例:[NOIP2012 提高组] 国王游戏

考虑两个相邻的人 \(i,j\),则 \(i\)\(j\) 前更优,当且仅当:

\[\max\left(\frac 1 {b_i}, \frac{a_i}{b_j}\right)\lt \max\left(\frac 1 {b_j}, \frac{a_j}{b_i}\right) \]

化简得 \(a_i\times b_i\lt a_j\times b_j\)
所以按 \(a\times b\) 升序排序即最优方案。

树上依赖贪心

考虑如下问题:给定一棵树,你需要以一定的顺序对节点进行操作,使得收益最大,且一个点能被操作当且仅当它的所有祖先都已经被操作。

如果没有 “先选父亲再选儿子” 这个限制,那么显然就是普通的 Exchange Argument。

有了这个限制后,我们考虑对于当前的最优元素,因为它肯定是越早被操作越好,所以如果它的父亲还没被操作,那么它会在它的父亲被操作后立刻被操作。
我们考虑用堆和并查集维护这个选点过程。每次取堆顶元素和它的父亲,合并成一个新的节点,再重新加进堆里。如果堆顶的父亲是根,或者它已经被操作过了,那么我们就可以直接操作当前节点了。
对于节点的合并规则,这也是一个关键点,同样可以使用 Exchange Argument 推导出,也可以直接感性推出。

而如果限制反过来,要求只有一个点的所有子孙都被操作过了才能操作这个点,那么把操作序列倒过来,就变成了上面的问题了。

例 1:[24ZR10D9T1] 宇宙

反转操作序列(记为 \(p\)),则答案为 \(\max_{i=1}^n n-i+d_{p_i}-1+a_{p_i}\),其中 \(d\) 为深度,\(d_1=1\)
去掉父亲儿子限制后的排序规则显然是按 \(d_i+a_i\) 升序。

考察 \(u,v\) 合并的规则(\(v\)\(u\) 的儿子):对于任意的另一点 \(w\)\((u,v)\)\(w\) 前更优当且仅当

\[\max(d_u+a_u, d_v+a_v-1, d_w+a_w-2)\lt \max(d_w+a_w, d_u+a_u-1, d_v+a_v-2) \]

化简得 \(\max(d_u+a_u, d_v+a_v-1)\lt d_w+a_w\),所以 \(u,v\) 合并后新节点的权值为 \(\max(d_u+a_u, d_v+a_v-1)\)

参考实现

例 2:【集训队作业2018】三角形

key observation:放置了 \(w_u\) 后,必然立刻收回其所有儿子的 \(w_v\)
所以对点 \(u\) 的操作分为:

  1. 放置 \(w_u\) 个石子。
  2. 收回 \(\sum w_v\) 个石子。

由于限制是先儿子后父亲,我们还是考虑反转操作序列,则操作有:

  1. 放置 \(\sum w_v\) 个石子。
  2. 收回 \(w_u\) 个石子。

\(u\) 的操作信息可以用二元组 \((mx,now)\) 表示,其中 \(mx\) 为历史最大值也即答案,\(now\) 为当前石子数。则 \(u\) 的信息为 \(\left(\sum w_v, \sum w_v-w_u\right)\)
考虑节点的合并:\(\left(\sum w_v, \sum w_v-w_u\right)+\left(\sum w_y, \sum w_y-w_x\right)=\left(\max(\sum w_v, \sum w_v+\sum w_y-w_u), \sum w_v+\sum w_y-w_u-w_x\right)\)

据此预处理出操作顺序,显然一个子树内节点的相对操作顺序是恒定不变的,对操作序列建线段树,线段树合并即可得到每棵子树的答案。

参考实现

反悔贪心

posted @ 2024-11-03 18:47  Accelessar  阅读(11)  评论(0)    收藏  举报