Loading

贪心专题 (Medium)

贪心专题 (Medium)

*P7831 [CCO2021] Travelling Merchant

首先,如果一个点没有出度,则它必定无解,一直删除没有出度的点,则剩余的图中每一个点都能不停走下去。

\(f_i\) 表示点 \(i\) 的答案,一个显然的转移是 \(f_i=\min_{(i,j,r,p)\in E}(\max(r,f_j-p))\)。如果能确定某一个点的答案,就可以根据这个转移来更新一些点的答案。更新这个点之后,这条边就没用了,可以删除。删除完之后,如果出现新的出度为 \(0\) 的点,这个点的答案就被确定了,可以继续拓扑排序用这个点更新。

但是由于这个图有环,所以可能无法确定任何点的答案。

考虑全局 \(r\) 最大的一条边,如果初始资产为 \(r\),则必定可以不停走下去。这启示我们可以从大到小考虑每一条边,当没有点用于转移时,找一条未被删除的 \(r\) 最大的边,用这条边更新其起点的答案,即 \(f_u=\min(f_u,r)\),那么这条边可以被删去。删去之后若出现出度为 \(0\) 的点就可以继续更新了。

这样类似于一个拓扑排序的过程,只是图中可能出现有环,这时候利用了题目的性质来“破环”,使得转移可以不停地进行下去。

P2751 [USACO4.2] 工序安排 Job Processing

考虑第一问。将洗衣机按照烘干一件衣服的结束时间排序,每一次贪心地取最小值,用堆维护即可。

考虑第二问。在洗完衣服的基础上,烘干衣服的开始时间不尽相同,不好考虑。不妨类似第一问求出,假设开始时间一样的前提下,每件衣服的烘干时间。设第一问每一件衣服的结束时间为 \(a_i\),第二问每件衣服结束时间是 \(b_i\)。将 \(a\)\(b\) 排序,那么答案为

\[\max(a_i+b_{n-i+1}) \]

即,让花费烘干时间最多的匹配结束时间最早的,这样尽可能平均。

*P3076 [USACO13FEB]Taxi G

首先每一个乘客的 \(\vert a_i-b_i\vert\) 是逃不掉的,先统计入答案中。

那么剩下的部分就是从某一个乘客的终点到另一个乘客的起点了。

将所有起点排序,将终点排序,\(0\) 算终点,\(m\) 算起点。每一次从第 \(i\) 个终点走到第 \(i\) 个起点,这样是最优的。

感觉不太好证,但是感受一下很对。

P6927 [ICPC 2016 WF] Swap Space

首先肯定要按照 \(a\)\(b\) 的大小关系分类。对于 \(a_i<b_i\) 的,当然是先选比较好,因为格式化完之后有的赚。按照 \(a\) 升序排序,这样可以先以较小的代价赚一些,后面可以少买一些额外硬盘。

对于 \(a_i\ge b_i\) 的部分,这些是不赚甚至亏损的。由于剩余空间要达到它们的 \(a\),所以希望剩余空间越多越好。按照 \(b\) 降序排序,这样每一次可以补充多一点剩余空间,后面剩余空间就多了。

*P5521 [yLOI2019] 梅深不见冬

邻项交换法。

显然每一个节点放花的时候,只有其儿子上面有花,儿子的后代没有花。而想要在儿子上面放花,这就是一个子问题,当然要继承儿子的最优解。

设点 \(i\) 的答案为 \(f_i\),那么考虑计算 \(f_x\)。注意到其遍历儿子的顺序会影响答案,即 \(f_x=\max(\sum_{j=1}^{i-1}w_{son_{j}}+f_{son_{i}})\),当然了,最后 \(f_x\) 要与 \(w_x\sum w_y\)\(\max\)

考虑两个儿子 \(i\)\(j\) 在什么情况下,\(i\) 会排在 \(j\) 的前面。当 \(i\)\(j\) 前面时要求满足:

\[\max(f_i,w_i+f_j)\lt\max(f_j,w_j+f_i) \]

想办法拆开这个 \(\max\),具体方法是利用 \(w\) 为正的性质。

  • 若前一项取得 \(f_i\),后一项取得 \(f_j\),那么有 \(f_i\gt w_i+f_j\gt f_j\),与要求矛盾,不满足要求。

  • 若前一项取得 \(f_i\),后一项取得 \(w_j+f_i\),显然能满足要求。

  • 若前一项取得 \(w_i+f_j\),后一项取得 \(f_j\),显然不满足要求。

  • 若前一项取得 \(w_i+f_j\),后一项取得 \(w_j+f_i\),那么在 \(w_i+f_j\lt w_j+f_i\) 时,即 \(w_i-f_i\lt w_j-f_j\) 时满足要求。

所以将儿子按照 \(w_i-f_i\) 排序之后 DP 计算答案即可。

**CF549G - Happy Line

非常神奇的题目。

直接模拟绝对不行。这个题需要找到“不变量”。

考虑相邻两个数 \(a_i\)\(a_{i+1}\),交换之后是 \(a_{i+1}+1\)\(a_{i}-1\),注意到 \(a_{i+1}\) 的位置减了 1,但是值增加了 1,位置加值不变,\(a_{i}\) 同理。

所以设 \(b_i=a_i+i\),由于要求结果升序,故将 \(b_i\) 排序之后输出 \(b_i-i\) 即可。

无解时存在某一个时刻相邻两个人相差 1,这就相当于存在两个 \(b_i\) 相等。

**CF798D - Mike and distribution

思维好题。

与其想怎么找,不如直接构造一组一定合法的解。

看到这种 \(\frac{n}{2}\) 一般要想到分组构造。将 \((a_i,b_i)\) 视作一个二元组,将所有二元组按照 \(a\) 从大到小排序。由于有一个 +1,先将 \(a_1\) 选上,剩下的两两分组。

总共有 \(\lfloor\frac{n}{2}\rfloor\) 组,每一组都能选一个。有结论每一组中任选一个就能满足 \(a\) 的限制。因为每一组的 \(a\) 的最小值大于等于下一组的 \(a\) 的最大值。所以无论这一组选了哪一个,其乘二之后,一个覆盖自己,另一个能覆盖下一个组的最大值。

所以在每一组中选出 \(b\) 较大的那一个,这样 \(b\) 的限制也被满足。

*P4053 [JSOI2007] 建筑抢修

反悔贪心模板题。

先按照报废时间升序排序。每一次尝试修复这个建筑,如果超过时间,那么必定需要报废一个建筑。用堆维护所有修复的建筑中,每一次先插入当前建筑,看总耗时是否超过限制,如果超过,就将耗费时间最长的建筑删除;否则将答案加一。

这样做是对的,因为如果报废的建筑是之前的某个建筑,说明这个那个建筑的修复耗时比当前建筑的修复用时要长,而且那个建筑已经修复完毕,所以删除之后,一定有时间修复当前建筑。否则修复这个建筑不优,耗时会减去当前建筑,相当于当前建筑没有加入过。

小Z的AK计划

仍然是反悔贪心。

按照坐标升序考虑每一个点,如果超时就删去之前选择的点中用时最大的点。

P8113 [Cnoi2021] 自我主义的平衡者

邻项交换法。

考虑最大值,最小值是类似的。

直觉是:如果想要分数更大,那么应该让预期比较低的人先投,这样前面可以把分数压低,后面就可以有很多满分。

结论是:升序排序序列之后取得最大值。

唉,邻项交换太神秘,搞不懂。

posted @ 2025-02-05 22:08  Terminator-Line  阅读(31)  评论(0)    收藏  举报