1. 题目背景与需求分析
这道公路维修问题来自洛谷P2242,是GESP C++五级认证的典型练习题。题目描述了一条长距离公路存在多处损坏点,需要安排维修队进行修复。由于维修队数量有限,我们需要合理规划维修区间,使得所有损坏点都被覆盖的同时,维修队的总移动距离最小。
这个问题看似简单,但蕴含着典型的贪心算法思想。在实际工程中,类似场景比比皆是——比如城市道路养护、电网巡检、物流配送路线规划等。理解这类问题的解法,对培养计算思维和解决实际问题都大有裨益。
题目给出的核心约束条件包括:
- 公路总长度为L(单位:公里)
- 共有N个损坏点,位置已知
- 最多可以派出M个维修队
- 每个维修队必须负责一段连续的区间
- 目标是最小化所有维修队的移动距离总和
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路与算法选择
2.1 贪心算法原理
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下最优决策的算法策略。它不像动态规划那样考虑全局最优,而是通过局部最优的选择,希望达到全局最优的结果。
对于本题,贪心策略的适用性体现在:
- 问题可以分解为一系列子问题(选择每个维修区间)
- 每个子问题的局部最优解能导向全局最优解
- 不需要考虑后续选择的影响
2.2 具体解题步骤
-
预处理阶段:
- 将所有损坏点位置排序(题目通常不保证输入有序)
- 计算相邻损坏点之间的距离差
-
关键观察:
- 如果M=1,显然总距离就是第一个到最后一个损坏点的距离
- 如果M≥N,每个损坏点一个维修队,总距离为0
- 实际有意义的情况是1<M<N
-
贪心策略:
- 每次选择相邻损坏点间距离最大的间隔不进行覆盖
- 这样相当于用M-1个间隔将损坏点分成M个区间
- 总距离 = 最后一个损坏点位置 - 第一个损坏点位置 - (M-1)个最大间隔和
3. 代码实现与详细解析
3.1 数据结构设计
cpp复制#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int L, N, M;
cin >>
