贪心
《算法设计与分析》期末复习
正确性证明
正确性证明(理论上)可以分两步:最优子结构和贪心选择(贪心策略)的证明
实际上做递归证明的话,可以同时保证两个正确性,因为最优子结构是基于正确的贪心选择生成的
下面证明一下 dijkstra:
线段覆盖
这个题变种很多啊
考虑右端点最靠左(或者说结束时间越早)的线段(任务)越优先被选择
考虑按结束时间从小到大排序即可
铺设道路
我觉得这个题目的思路蛮有意思的
首先我们填平 \(a_1\)
考虑对于 \(a_i < a_{i+1}\) 有 $$ ans += (a_{i+1} - a_i) $$
假如我们遇见了一个单调的 \(a_1, ..., a_n\);这显然成立
考虑对于多个“山峰”,山峰下降的部分不会做出贡献,因为在上升的时候“顺便”覆盖了
分组
我当年真做过这题?
先看数据范围,理论上支持 \(O(nlogn)\) 的时间复杂度
其次从约束条件考虑贪心:要使人最少的组最多
为了方便判断是否在数值上连续,首先对整个序列排序,这样就可以从小到大去做处理
如果每个数字只出现一次呢?显然天然的按连续性去分组就是最优解;问题出现在如果有两个相同的数字,这两个相同的数字会进入到不同的队伍中,从而对后面的数据产生影响
考虑维护一个 \(n_i\) 记录第 \(i\) 组的人数,\(q_i\) 记录第 \(i\) 组目前最大的数字
对于当前数值 \(a_i\),二分查找 \(q_i + 1 = a_i\),然后把 \(a_i\) 放进 \(n_i\) 最小的那一组里面
时间复杂度 \(O(nlogn)\)