1. 题目背景与核心需求解析
公路维修问题是一个经典的区间覆盖类算法题目,源自洛谷P2242。题目描述的是:在一条长度为L的公路上有N个损坏点,现在需要选择M个区间进行维修,要求覆盖所有损坏点,并且使得这些维修区间的总长度最短。
这个问题的实际意义非常直观——市政部门在有限的维修资源(M个施工队)下,如何高效安排维修路段,既能确保所有损坏点都被覆盖,又能最小化总施工距离。这直接关系到公共资源利用效率和交通影响最小化。
1.1 问题建模要点
我们需要将实际问题转化为算法模型:
- 将公路视为数轴,损坏点视为数轴上的点
- 维修区间就是覆盖这些点的线段
- 目标是最小化M条线段的总长度
关键约束条件:
- 必须覆盖所有损坏点
- 最多使用M个区间
- 区间可以重叠
1.2 输入输出规范
标准输入格式:
- 第一行:三个整数N, M, L(1≤M≤N≤20000,N≤L≤10^9)
- 第二行:N个整数,表示损坏点位置(已排序)
输出要求:
- 一个整数,表示最小总长度
示例输入:
code复制7 2 50
2 5 10 12 15 20 25
对应输出:
code复制9
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法思路与贪心策略
2.1 基础贪心思想
这个问题可以采用贪心算法解决,核心思路是:
- 先计算所有相邻损坏点之间的距离
- 选择最大的M-1个间隔不进行覆盖
- 总长度 = 最右损坏点 - 最左损坏点 + 1 - 这些间隔的和
为什么这样可行?因为每个不覆盖的大间隔相当于把公路分成一段独立维修区间,少覆盖一个大间隔就能减少一个维修区间。
2.2 具体实现步骤
- 对损坏点位置排序(题目已保证有序)
- 计算相邻点间距:dist[i] = pos[i+1] - pos[i] - 1
- 对间距数组排序(降序)
- 取前M-1个最大间距
- 计算结果:总长 = (pos[N-1]-pos[0]+1) - sum(前M-1个间距)
2.3 算法正确性证明
贪心选择性质:每次选择最大的间隔不覆盖,可以最大化减少总长度。因为:
- 总长度 = 连续覆盖长度 - 不覆盖的间隔
- 要最小化总长度,就要最大化不覆盖的间隔
- 因此应该优先选择最大的间隔不覆盖
最优子结构:在做出贪心选择后,剩下
