贪心+构造练习

菜就多练。

贪心和构造有一定相似性(都不会做),放在一起做吧。

1. [ABC123D] Cake 123

link

热身简单题。利用进行贪心。

发现排序后都取端点一定是最值,然后随便一个序列中向后挪一个位置都有可能是次大值。

于是用堆维护,每次弹出最大的,然后向后拓展三个状态塞到堆里面。注意可能一个状态会被多次拓展到,要标记去重。

反正数据范围小,\(O(k\log k)\)(?,总之能过。

另一种做法是先求前两个序列中前\(k\)个和,再用这些数与第三个序列求前\(k\)个和。

2. P6155 修改

link

排序不等式,邻项交换,直觉。

首先注意到修改过的数要尽量少,可以随便证一下。

排序不等式,假设已经求出每个数的修改次数,那么就按排序不等式逆序和加起来。

来求每个数的修改次数,先把原数组排序,考虑在值域上依次枚举,维护一个集合\(S\)表示手上还没被用来填值域的数。

枚举到\(v\)时,把等于\(v\)的原数组中的数插入到\(S\)中,现在考虑从\(S\)中取哪一个数进行若干次修改到\(v\)

如果\(S\)中有\(v\),那就直接填。如果没有,可以证明用\(S\)中最接近\(v\)的数去填是最优的,考虑邻项交换

注意到\(S\)中插入的数按插入顺序单增,且都\(\le v\),于是用栈维护一下\(S\)就好。注意如果枚举到一段值域上时\(S=\emptyset\),需要跳过这一段。

\(O(n)\)

3. [AGC004D] Teleporter

link

树上贪心,从叶子考虑。关注不变的事情(不争的事实),关注答案的形态

发现有\(n\)个点\(n\)条边,且都能到\(1\),于是画一下就知道是一棵基环树。

首先可以证明\(1\)一定是自环:若不是,设\(u\)\(1\)经过\(k\)步,那么\(fa_u\)\(1\)就不是\(k\)步,矛盾。

于是可以转化题意为:以\(1\)为根的一棵树,要使得最大深度\(\le k\),最小化操作次数。

关注一些总是不变的事情:最深的叶子在操作后的深度恰好为\(k\)。否则,我们总是可以调整修改的边,使之尽可能向上,因为这样总是可能让操作的子树包括其他深度超过\(k\)的点。

于是DFS,过程中如果当前子树的高度为\(k\),那就操作一次,并且使这棵子树对上方节点计算子树高度的影响为\(0\)

\(O(n)\)

4. [AGC007B] Construct Sequences

link

看到单调性构造想差分。利用反函数性质将下标化简。

\(\{a_n\}\)单调递增,\(\{b_n\}\)单调递减,那么差分一下,设:

\[\begin{aligned} a_k-a_{k-1}=x_k\texttt{且} b_k-b_{k+1}=y_k\\ \texttt{即}a_k=\sum\limits_{j\le k} x_j\texttt{且} b_k=\sum\limits_{j\ge k} y_j\\ \texttt{其中}1\le x_j,y_j,a_k,b_k\le 10^9 \end{aligned} \]

来看剩下的限制,为了\(a_{p_i}+b_{p_i}>a_{p_{i-1}}+b_{p_{i-1}}\),我们尝试令\(a_{p_k}+b_{p_k}=C+k\)

为了利用上差分,我们代换一下,设\(q_{p_k}=p_{q_k}=k\),即\(q\)\(p\)的反函数。对上面的式子中的\(k\)同时作用上一个\(q\),可以得到\(a_{p_{q_k}}+b_{p_{q_k}}=C+q_k\)\(a_k+b_k=C+q_k\)

尝试相邻两项相减来做差分,即\((a_k+b_k)-(a_{k-1}+b_{k-1})=x_k-y_{k-1}=q_k-q_{k-1}\)

于是一组合法的解为\(x_k=y_k=q_k\)\(q\)\(p\)可以求得,于是\(a_k=\sum\limits_{j\le k}q_j,b_k=\sum\limits_{j\ge k} q_j\)即可。

5. P4053 [JSOI2007] 建筑抢修

link

反悔贪心,先随便贪然后设计反悔。

首先随便贪,但要有一定的正确性。这里的限制主要是报废时间,于是报废时间小的要先做。

如果做到一个位置不得不报废了,就查看要不要反悔,如果之前做过的最长耗时比这个位置的用时长,那么用这次的替换之显然更优,因为使得总用时减小了,并且这样一定不会使当前位置报废。

就这样反悔,用大根堆维护最长耗时,\(O(n\log n)\)

也有不反悔的做法,正着做,每个任务显然要尽量在贴近报废时去做,并且优先做用时少的,用线段树/ODT维护区间推平即可,\(O(n\log n)\)

6. P2209 [USACO13OPEN] Fuel Economy S

最直接的想法是,每次到一个费用比较小的加油站再加油。

那么可以这样想,每次到一个加油站,我们都想判断能不能到一个费用比它更小的加油站加油。

于是首先可以单调栈搞出来每个位置后面第一个费用比它小的。

由于有油箱大小的限制,判断在不加爆油箱的前提下,能否通过加一些油走到下一个比它费用更小的加油站。如果可以,就这么干,否则直接把油箱加满,往前走。

这样是因为如果到不了,那么最终必然会走到一个费用比它大的位置,不如当前加满油箱。

是 greedy stays ahead 的想法。

7. P7831 [CCO 2021] Travelling Merchant

发现首先可以类似拓扑排序地判掉一些不在环中的点。其实是先建反图,然后拓扑排序。于是现在剩下了一些环。

考察当前图中 \(r\) 最大的一条边,可以发现原图上 \(ans_u\le r\)。发现有类似 DP 的东西,\(ans_u=\min\{\max\{ans_v-p,r\}\}\),但是最大的问题是有环。对于 \(r\) 最大的边,用 \(r\) 更新答案之后断掉它。这是可能又出现了类似 DAG 的结构,刚才的 DP 就可以做了。重复这个过程即可。

正确性考虑当我们断掉一条边产生了类似 DAG 的结构时,必然存在点一定要走到经过它的环中,用它来更新显然正确。

类似不断更新上界,最后最优秀的上界就是答案。

8. P2587 [ZJOI2008] 泡泡堂

完全体田忌赛马。

9. P5521 [yLOI2019] 梅深不见冬

10. P1269 信号放大器

11. P2127 序列排序

12. P1792 [国家集训队] 种树

13. P3615 [JOISC 2016 Day2] 如厕计划

14. CF436E Cardboard Box

posted @ 2024-12-25 19:55  RandomShuffle  阅读(12)  评论(0)    收藏  举报