2 条题解
-
-2
题解
1. 把题目翻译成“区间覆盖”
题目要求:
并且对于每个 ,至少存在一个 ,满足:
注意:
就等价于:
所以每一对 就可以看成一个区间:
题目实际上是在问:
用 个区间覆盖所有的 ,使这些区间长度之和最小。
2. 先把所有 排序
假设排序后:
相同的数没有必要重复考虑,所以可以去重:
例如:
原序列: -5 0 10 4 0 排序: -5 0 0 4 10 去重: -5 0 4 10
3. 一个区间覆盖哪些数?
假设一个区间:
覆盖了 (a_l) 和 (a_r)。
因为:
所以中间所有数也一定满足:
也就是说:
一个区间覆盖排序后的数时,它覆盖的一定是一段连续的数。
例如:
-5 0 4 10 |---------|如果覆盖
-5和4,那么0也必然被覆盖。
4. 一个区间覆盖一段数时,最优怎么取?
假设一个区间负责:
那么必须有:
以及:
我们要最小化:
所以显然应该让区间刚好贴住两边:
此时贡献:
因此:
覆盖一段数的最小代价,就是这一段最大值减最小值。
5. 分段
这是这题最重要的一步。
题目允许不同区间互相重叠,例如:
和
假设:
两个区间为:
它们有重叠部分。
原来的代价:
把它们合并成:
代价:
两者之差:
因为:
所以:
因此:
也就是说:
两个重叠区间合并之后,答案不会变差。
所以我们总能找到一个最优方案,使有效区间之间没有重叠。
于是排序后的:
就可以看成被分成若干连续段。
例如:
a1 a2 a3 | a4 a5 | a6 a7每一段对应一个区间。
而且如果最后只用了少于 个区间,多出来的区间可以取:
它的长度是 (0),不会影响答案。
所以实际上是:
最多使用 段。
6. 一个区间
如果只使用一个区间,那么它必须覆盖:
所以区间就是:
答案:
例如:
-5 0 4 10一个区间:
[-5,10]代价:
7. 如果增加一个区间呢?
现在允许使用两个区间。
假设在:
之间切一刀:
a1 a2 ... ai | ai+1 ... am那么两个区间的代价:
原来一个区间的代价:
两者相差:
整理:
所以:
在 和 之间切一刀,可以节省 。
8. 应该在哪里切?
我们有:
相邻差分别是:
$$a_2-a_1,\quad a_3-a_2,\quad \dots,\quad a_m-a_{m-1}$$如果允许使用 个区间,就最多可以切:
刀。
每切一刀,就节省一个相邻差。
所以为了让最终答案最小,我们应该选择:
9. 为什么选最大的?
假设所有相邻差为:
5 4 6如果只能切一刀:
- 切
5,答案减少 5 - 切
4,答案减少 4 - 切
6,答案减少 6
当然应该选择
6。所以就是:
$$\text{答案} = (a_m-a_1) - \text{最大的 }k-1\text{ 个相邻差之和}$$如果不同的数只有 (m) 个,那么最多只能切 (m-1) 刀,因此实际切刀数为:
10
具体做法非常简单:
- 读入所有 (c_i)。
- 排序。
- 扫一遍,跳过重复元素。
- 计算相邻不同元素之间的差值。
- 将这些差值从大到小排序。
- 初始答案为最大值减最小值。
- 减去最大的 (k-1) 个差值。
- 如果不同元素数量不足 (k),就全部切掉。
- 切
信息
- ID
- 2766
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- (无)
- 递交数
- 16
- 已通过
- 11
- 上传者