1. 问题背景与理解
这道题目描述了一个典型的任务调度问题:我们有一个修理工人和N个需要修复的建筑,每个建筑有两个关键参数——修复所需时间T1和截止时间T2。工人一次只能修理一个建筑,如果在截止时间前无法完成修复,这个建筑就会报废。我们的目标是合理安排修理顺序,使得能够修复的建筑数量最大化。
这个问题在实际生活中有很多类似场景,比如:
- 医院急诊室的病人救治顺序安排
- 服务器任务调度中的作业处理
- 项目管理中的关键路径规划
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础贪心思路分析
2.1 直观贪心策略
最直观的贪心策略可能是按照修复时间T1从小到大排序,优先修复耗时短的建筑。但这样会忽略截止时间的限制,显然不是最优解。
另一个直观想法是按照截止时间T2排序,也就是所谓的"最早截止时间优先"(Earliest Deadline First, EDF)策略。这在很多调度问题中确实是有效的,但在这个问题中单独使用EDF策略仍然不够。
2.2 EDF策略的局限性
假设我们有以下三个建筑:
- T1=5, T2=10
- T1=5, T2=10
- T1=1, T2=2
按照EDF策略排序后顺序是3→1→2,但这样只能修复建筑3。而实际上最优解是修复建筑1和2。
这说明单纯按截止时间排序还不够,我们需要更聪明的策略。
3. 后悔贪心算法详解
3.1 算法核心思想
后悔贪心(Regret Greedy)是一种改进的贪心算法,它允许我们在做出选择后,有机会"反悔"并调整之前的选择。在这个问题中,具体思路是:
- 首先将所有建筑按截止时间T2升序排序
- 维护一个最大堆,存储当前已选择修复的建筑所需的修复时间
- 遍历每个建筑:
- 如果能直接修复(当前总时间 + 该建筑修复时间 ≤ 截止时间),则修复
- 如果不能直接修复,则考虑"反悔":
- 检查堆顶(当前已修复建筑中耗时最长的)
- 如果当前建筑修复时间比堆顶小,则替换(相当于放弃之前那个耗时长的建筑)
- 这样总修复时间减少,为后续建筑争取更多机会
3.2 算法正确性证明
这个算法的正确性基于以下观察:
- 按截止时间排序确保了我们先处理更紧急的任务
- 当无法处理当前任务时,我们总是尝试替换掉已选任务中耗时最
