贪心题目汇总
贪心
医生厨
拉起窗帘
首先就是一个贪心,先整体放再单个放。
然后就在考虑从二者效率关系上比较优劣。
但是整体贡献是可以直接搞的。
这是可以线性预处理的。然后就出来了个单峰函数,二分即可。
COCI2021-2022#4 Parkovi
问题描述:一个很经典的树上贪心。在树上的所有点中选择 \(k\) 个关键点 \(p_i\),求 \(\min \max \min dis(i,p_j)\) 的值以及其大小。
问题解决:基于贪心:从叶子往上,能不放就不放,到一定要放的时候再放。具体地,记录 \(f_i\) 表示 \(i\) 这棵子树内距离 \(i\) 最远的未被覆盖的点的距离;\(g_i\) 表示在 \(i\) 这棵子树内距离 \(i\) 最近的已经染色的点的距离。实现见代码。
想到的过程:这是以前写过的,应当对这个贪心有基本认识,就像今年 CSP T2 一样。
CSP-S2019 划分
贪心好题!
考虑 \(f_{i,j}\) 表示前 \(i\) 个数,最后一段为 \([j,i]\) 的最小价值。这会有 36pts。
最后一段长度越小越优。证明:对于长度确定的 \(a + b = len, a \le b\),那么 \(b\) 越小 \(a^2 + b^2\) 越小(由均值不等式)。
记录 \(d_i\) 为 \(i\) 结尾最优情况下最后一段的长度。\(f[i] \gets f[j] + (pre[i] - pre[j])^2\) 时 \(pre[i]-pre[j] \ge d[j]\),即 \(pre[i] \ge pre[j]+d[j]\)。我们维护符合条件最大的 \(j\) 即可。
注意数据范围,最后一个 sub 要开 __int128。
NFLS-dfs序-Gym 105170B
这道我做了 3h 的贪心题。。。还是那句话,思路有了,你要思考简化并给出一个简明的解决方案。而不是敲完屎山然后对着看。
原本将儿子节点分为 \(A,B,C,D\) 四类,并且进行分讨。状态的糟糕设计也使得跑了一遍最大值然后又跑了一遍最小值。状态其实没必要为”当前节点所在子树中 \(dfs\) 序最大/最小值“其实奇偶分开记就行了。对于 \(B,D\) 的转移只需要分讨有没有 \(A,C\) 即可;\(A,C\) 本质上不用加以区分,直接排序计入答案然后劈一半即可。注意细节,画下图就能明了。
interval - NFLSOJ
带反悔的贪心
即通过堆(大根堆、小根堆)来维护当前贪心策略的最优解,若发现最优解不对,就退回上一步,更新最优解。
将区间按照左端点排序,从左向右遍历区间。当前区间为 \(a\),取出当前右端点最左的区间,可以就匹配。
如果不可以,去看看已经匹配中的 \(b,c\),\(c\) 地右端点是否在 \(a\) 左侧,若是,则 \(a,b\) 匹配,因为右端点越左说明在后面匹配上的可能就越大。
树上配对 - NFLSOJ
贪心、性质
第一时间应当想到树上的处理,核心是父亲与儿子之间的关系。比赛的时候想到了贪心:能在子树里搞的就在子树里搞。但是写挂了,写的太繁琐。之后用神犇的题解姿势过的。对于每个点,记录 \(in,out\) 两个动态数组,对于每次的加入边,根据 \(in\) 和 \(out\) 的 \(siz\) 大小进行调整。
染色
一开始在想 DP。困惑在于染色策略不能明确。不从计算成本增加的过程出发,而去考虑如何削减成本。
对于询问 \((l,r)\),答案上界为 \((r-l) \times 2\),对于 \(a_i = a_j\) 我们在 \([i,j]\) 都染为 \(a_i\) 可以削减 \(1\) 的成本。那么我们就是要对于这种段,使得这种段尽量多。
这明显的可以贪心。对于每一个位置的下一个相同颜色位置为 \(b\),那么对其做一遍后缀和可以得到右边离 \(i\) 最近的右端点 \(nxt_i\),\([i,nxt_i]\) 都染成 \(a_{nxt_i}\) 的颜色,明显这是最优的。这样我们会省多少成本?就是跳的段的个数。那么考虑用并查集维护(倍增也行,但会被卡常),维护的是当前点 \(i\) 的最右边会跳到哪里。离线将询问放到 \(r\) 上,从左到右每次合并维护即可。
关键在于思维转换到“如何削减成本”,就可以想到贪心了。