区间贪心问题总结
假设有 \(n\) 个区间,考虑将值域离散化,使其与 \(n\) 同阶。
CF1701D
给定一些区间,给它们分别赋上区间内一个值,使得这些值不重复。
对区间右端点排序,遍历一遍,每次赋值尽量靠近左端点的值。
时间复杂度 \(O(n \log n)\)。
ZOJ2667
有若干个带权值区间,选定几个区间,使得它们互不相交,且权值和最大。
先按照右端点排序,然后 \(dp[i]\) 表示考虑右端点坐标在 \(i\) 之前的区间最大的权值。\(dp[i]\) 从 \(dp[i-1]\) 和 \(\max \limits_{j,r_j==i}\{dp[l_j - 1]+w_j\}\) 转移而来。
时间复杂度 \(O(n)\)。
BZOJ1745
有若干个权值为 \(w_i\) 的区间,对于每个区间取选中值 \(v_i \le w_i\),使得每一个数字对应选中值不超过 \(c\),且选中值和最大。
如果 \(c=1\),那么是非常经典的问题。我们考虑对右端点排序,然后按照顺序如果当前时段已经有区间在了(可以记录上一个区间结束的时间),那么就跳过;否则用这个区间。考虑证明:对于每一个时段,在当前时段之前的飞机已经确定的情况下,考虑可以使用的相邻两个区间 \(a,b,r_a < r_b\),如果两个区间不交叉,那么两个区间都可以用上;如果两个区间交叉,那么只能在这两个区间中选一个区间,并且之后的区间选择中,由于选 \(a\) 留下了更大的空间,一定不劣。
考虑 \(c>1\) 的推广。可以把每个区间拆成 \(w_i\) 个权值为 \(1\) 的区间,仍然按照右端点排序。