1. 问题背景与需求分析
公路维修问题是算法竞赛中的经典题型,主要考察选手对贪心算法和区间处理的理解能力。题目描述通常为:在一条长度为L的公路上有N个损坏点,现在需要选择M个区间进行维修,要求覆盖所有损坏点,并使得这些维修区间的总长度最短。
这类问题在实际工程中有着广泛的应用场景。比如市政部门需要合理安排道路维修施工,既要确保所有损坏路段都被覆盖,又要尽量减少施工对交通的影响。通过算法优化,可以科学地规划施工方案,降低工程成本。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路与算法选择
2.1 贪心算法原理
贪心算法是解决此类问题的有效方法。其核心思想是:在每一步选择中都采取当前状态下最优的选择,从而希望导致全局最优的结果。对于公路维修问题,我们可以将损坏点排序后,计算相邻点之间的距离,然后选择最大的M-1个间隔作为不维修的区间。
这种方法的正确性基于以下观察:要使总维修长度最小,就应该让未被覆盖的间隔尽可能大。因此,我们优先保留最大的间隔,这样剩下的维修区间自然就会最小化。
2.2 具体实现步骤
- 首先将所有损坏点的位置进行排序
- 计算相邻损坏点之间的距离
- 将这些距离从大到小排序
- 选择前M-1个最大的距离作为不维修的间隔
- 总维修长度就是第一个损坏点到最后一个损坏点的距离,减去这些不维修间隔的总和
3. 代码实现与细节处理
3.1 数据结构选择
使用vector存储损坏点位置和间隔距离是最方便的选择。排序可以直接使用STL的sort函数,时间复杂度为O(N log N),完全能够满足题目要求。
cpp复制#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int N, M;
cin >> N >> M;
vector<int> points(N);
for(int i=0; i<N; ++i) {
cin >> points[i];
}
sort(points.begin(), points.end());
vector<int> gaps;
for(int i=1; i<N; +
