贪!!心!!
贪||你妈的||心!!
贪心是一个依靠思考加猜想得到的算法,一般贪心的复杂度都很低,区分度很大,贪心的难度在于怎样猜及其证明。
除了练题我不知道有什么方法可以增强贪心能力。
1. 练习题
设 \(f_x\) 表示想在 \(x\) 节点放梅花所需最少梅花数量。
对于节点 \(x\) 的子节点 \(y\),只需要 \(y\) 节点放满梅花,我们可以回收 \(y\) 子树内所需的其他梅花,即 \(f_y - w_y\),我们贪心的回收尽可能多的梅花,所以我们可以对 \(x\) 的子节点按照 \(f_y - w_y\) 排序,依次枚举,最后再考虑放满 \(x\) 节点即可。
-
证明:假设有两对数 \((f_1,w_1),(f_2,w_2)\),且 \(f_1 - w_1 \geq f_2 - w_2 \Rightarrow f_1 + w_2 \geq f_2 + w_1\)。
- 若按照 \(1,2\) 的顺序,则总花费为 \(f_1 + \max(0,f_2 - (f_1 - w_1)) = \max(f_1,f_2 + w_1)\)。
- 若按照 \(2,1\) 的顺序,则总花费为 \(f_2 + \max(0,f_1 - (f_2 - w_2)) = \max(f_2,f_1 + w_2) = f_1 + w_2\)。
则由 \(f_1 + w_2 \geq f_1\),得 \(f_1 + w_2 \geq \max(f_1,f_2 + w_1)\),即得按照 \(1,2\) 顺序更优。
则以 \(f_x - w_x\) 排序最优。
得证。
复杂度 \(\mathcal{O}(n\log{n})\),瓶颈在排序。
II CF798D Mike and distribution
一道贪心构造。
我们需要选 \(\left\lfloor\frac n 2 \right\rfloor + 1\) 个点,相当于每两个点我们需要选较大的那个点,我们先按照 \(a\) 排序,考虑 \(n\) 为奇数,则我们可以先选 \(a\) 最大的点,然后依次枚举两个点,找到 \(b\) 更大的选。
- 这样对于 \(a\),由于我们先选了最大的点,所以无论后面枚举的两个点选哪个,都可以使总数 \(\geq \frac {S_a} 2\),因为对于每一个我们选择的点 \(x\),总可以 匹配 另一个未被选择的点 \(y\),使 \(a_y \leq a_x\)。
- 对于 \(b\),由于我们选了两个点中 \(b\) 更大的点,所以总数不会小于一半。
最后因为多选了一个点,所以总数一定大于一半。
对于 \(n\) 为偶数,随便多选一个即可。
我们贪心的选择点使得当前时间尽可能早,我们按照 \(T2\) 排序,枚举选择能加的就加,若不能加,则判断是否可以替换掉选择的点,使得当前时间更早,这样一定不劣,可以简单用优先队列维护。
不是很会怎么用数学证明。
复杂度 \(\mathcal{O}(n\log{n})\)。
一道奇怪的贪心?假算法差点A了
显然先按照位置 \(x\) 排序,然后我们枚举机房,直接花时间,然后贪心的选择当前选过的节点,删除一些(可以不删)直到使总时间 \(\leq m\),这样我们求个 \(\max\) 即可,可以用优先队列维护当前选的机房。
- 这样我们相当于 固定选一个节点,贪心的找其他节点使贡献最大,这里贪心的找最小时间,显然是正确的。
复杂度 \(\mathcal{O}(n\log{n})\)。