【算法复健】贪心
题单-贪心 做题整理
时隔多年再次刷贪心题单,代码细节没什么好说的。
本次笔记主要集中于 证明贪心的正确性。
P2240 【深基12.例1】部分背包问题
注意金币可以随便分割。
也就是说事实上金币本身就可以用单位价值衡量。
单位价值越高,当然是拿越多越好。
因此按照单位价值降序排序依次取即可。
P1223 排队接水
首先平均等待时间最优等效于总等待时间最优。
直观上正确做法就是按照接水时间升序排序,下面证明该想法的正确性。
首先我们假设安排的顺序是 $p_1,p_2,\dots,p_n $。
$p_i $等待时间为 $\sum_{j=1}^i T_{p_j} $。
那么总等待时间是:
对于这个式子修改一下枚举方式,换成计算每个人对于等待时间的贡献:
事实上这个时候可以看作两个数列 ${T_{p_k}} $与 ${w_{x_k}=n-x_k} $的排序求和,需要引入一个排序不等式:
若 $a_1 \leq a_2 \leq \dots \leq a_n $且 $b_1 \geq b_2 \geq \dots \geq b_n $,则
其中 $p $是任意排列,这个时候 ${T_{p_k}} $升序并且 ${w_{x_k}} $降序就可以使得总和最小,即接水时间升序排列即可。
下面证明排序不等式:
首先尝试调整两组元素,假设 $a_s\leq a_t,b_i \geq b_j $:
即:
那么对于一个全都是升序排列的 $\sum a_ib_i $,我们对其进行有限次逆序对换,值都不会增加。
当 ${a} $升序并且 ${b} $降序的时候,无法再进行逆序对换,这时总和最小。 \(\square\)
P1803 凌乱的 yyy / 线段覆盖
贪心策略是按照结束时间 $b_i $升序排序然后依次选择。
如果当前活动开始时间不早于上一个已选活动的结束时间则选择该活动。
由于这道题是一道典型的贪心题目,我会归纳一些常见性质,加上证明过程。
贪心选择性质
对于最优解中的第一个活动 $X $,结束时间为 $e_X $。
如果 $X $不是最早结束的活动,那就存在一个活动 $Y $使得 $e_Y \leq e_X $。
- 若 $Y $与 $X $不重叠,那么 $Y $可以被 $X $替换并且有更大的选择空间。
- 若 $Y $与 $X $重叠,如果选择 $Y $,后续与 $Y $不重叠的活动同样也与 $X $不重叠,甚至 $X $留下更多空间, $X $明显是不劣的。
所以第一步选择结束时间最早的活动是不会错过最优解的。
最优子结构性质
按照上一个性质往下推,我们可以拥有一个较早结束的活动块 $\chi $。
这个活动块与前面的 $X $等效,比它晚结束的具有相同活动个数的活动块 $\gamma $并不会比它更优。
可以发现这个算法每次都能做出局部最优解的同时不耽误全局最优解。
事实上,正确的贪心策略都要题目能够满足以上性质。
数学归纳法证明
归纳奠基: $n=1 $时显然选了就是最优解。
归纳假设: 假设对于 $n\leq k $的情况,贪心策略都能获得最优解为 $w_k $。
归纳递推: 考虑 $n=k+1 $的情况:
- 找到最早结束的活动 $A_1 $;
- 去除所有与 $A_1 \(冲突的活动(\)s_i<e_1 $);
- 剩余活动中规模 $\leq k $,由归纳假设知道贪心能获得最优解 $w_k $;
- 因此 $w_{k+1}=w_k+1 $。
以上就完成了证明。 \(\square\)
P1090 [NOIP 2004 提高组] 合并果子
看似摘果子,实则哈夫曼编码。
正解是选择当前体力消耗最小的两堆,其实也是哈夫曼编码的构造思想。
事实上就是构造一棵树使得最终总权值最小。
最优子结构性质
设 $T $是一棵最优合并树(对应最优合并方案)。
考虑任意一个内部节点 $x $,对应的两个子节点是在某一步合并的。
假如固定这两堆果子的合并步骤,剩下的合并也必须是最优的,否则还有更优解。
贪心选择性质
首先思考:重量最小的两堆果子一定在第一次就被合并吗?
事实上不一定在第一次,但一定会在某一步被单独合并,并且是不劣的。
证明:
存在一个最优方案,使得重量最小的两堆是 兄弟节点(即在某一步会被合并)。
设最小堆和次小堆为 $m_1, m_2 $。
假设在某个最优方案中它们不是兄弟节点。
设 $m_1 $的兄弟是 $n_1 $, $m_2 $的兄弟是 $n_2 $。
这时候 $m_1\leq m_2,m_1 \leq n_1,m_2\leq n_2 $。
比较调整前后贡献变化:
因此最小的两堆作为兄弟是不劣的。
接下来合并最小的两堆之后,又是等效的合并果子问题。
数学归纳法证明
归纳奠基: $n=2 $的时候只能合并一次显然最优。
归纳假设: 假设 $n \leq k $均能获得最优解 $w_k $。
归纳递推: 考虑 $n=k+1 $的情况:
通过贪心选择性质可知,可以先合并最小的两堆。
这时候又变成了 $k $堆的问题, $w_{k+1} = (a_{m_1}+a_{m_2}) + w_k $。
因此贪心策略正确。 \(\square\)
P3817 小A的糖果
正解是从头检查 $a_i+a_{i+1} $,只要不满足要求就将 $a_{i+1} $改造为 $x-a_i $。
贪心选择性质
要保证所有相邻对是满足条件的。
-
对于第一对 $(a_1,a_2) $,要么减少 $a_1 $要么减少 $a_2 $。
如果减少 $a_1 $,只能对 $(a_1,a_2) $这一对有作用;
而减少 $a_2 $可以对后续产生影响,并且不劣。 -
对于中间某一对 $(a_i,a_{i+1}) $,
若减少 $a_i $会使得左侧已经完善的关系被破坏,
因此减少 $a_{i+1} $是更加合适的选择。
归纳证明
假设已经处理完前 $i-1 $对,现在检查 $(a_i,a_{i+1}) $。
若该对 $a_i + a_{i+1} > x $,必须减少 $a_i + a_{i+1} - x $。
这时候只能减少 $a_{i+1} $,理由同前。
P1478 陶陶摘苹果(升级版)
首先只需要考虑能够到的苹果。
发现苹果之间的差距只有体力消耗 $y_i $可以造成影响,其他性质都等价。
因此只需要按照 $y_i $升序排列,能取则取,一定是最优的。
P5019 [NOIP 2018 提高组] 铺设道路
策略是从头开始,只要 $d_i > d_{i-1} $,就把 $|d_i-d_{i-1}| $填上。
数学归纳法证明
归纳奠基: $n=1 $时显然需要 $d_1 $次操作。
归纳假设: 假设 $n<k $道路贪心策略正确。
归纳递推: 考虑 $n=k $时:
若先填平前 $k-1 $段, $ans_{k-1} = \sum_{i=1}^{k-1}\min(0,d_i-d_{i-1}) $。
此时前 $k-1 $段是 $d_{k-1} $深度,
那么还是加上 $\min(0,d_k-d_{k-1}) $,策略正确。 \(\square\)
P1208 [USACO1.3] 混合牛奶 Mixing Milk
(此处待补)

浙公网安备 33010602011771号