1 条题解
-
0
题目理解
我们有 个同学,第 个同学在 时刻到达车站。摆渡车往返一趟需要 分钟。我们需要安排摆渡车的出发时间,使得所有同学的等车时间之和最小。
关键规则:
- 摆渡车容量无限
- 摆渡车回到起点后可以立即出发
- 等车时间 = 上车时间 - 到达时间(如果为负则取0)
问题分析
1. 基本观察
如果摆渡车在某个时刻 出发,那么:
- 所有在 之前到达的同学都会在 时刻上车
- 这些同学的等车时间 = (如果 )
- 在 之后到达的同学需要等待下一班车
2. 发车间隔的影响
由于摆渡车往返需要 分钟,如果我们在时刻 发车,那么下一班车的最早发车时间是 。
因此,问题转化为:将时间轴划分为若干区间,每个区间长度为 (或更长),每个同学被分配到某个发车时刻,使得总等待时间最小。
动态规划解法
1. 状态设计
设 表示考虑前 个同学(按到达时间排序后的前 个)的最小总等待时间。
但是这样还不够,因为我们还需要知道最后一班车的发车时间。
更好的状态设计: 表示第 个同学是某班车的最后一名乘客时,前 个同学的最小总等待时间。
2. 状态转移
对于每个 ,我们枚举上一班车的最后一名乘客 (),那么:
- 第 到第 个同学乘坐同一班车
- 这班车的发车时间至少是
- 具体发车时间可以延迟到某个最优时刻
更精确的状态转移:
$$dp[i] = \min_{0 \leq j < i} \left\{ dp[j] + \text{cost}(j+1, i) \right\} $$其中 表示第 到第 个同学乘坐同一班车的最小等待时间之和。
3. 计算 cost(l, r)
对于区间 的同学,如果他们乘坐同一班车:
- 发车时间必须 (最后一个同学到达时间)
- 为了最小化等待时间,发车时间应该尽可能早,即
等待时间之和为:
算法优化
1. 时间离散化
由于 最大可达 ,直接枚举所有可能时间不可行。但注意到:
- 发车时间只可能在同学到达时间的基础上稍微延迟
- 延迟时间不会超过 (否则可以提前发车)
因此,对于每个区间 ,我们只需要考虑发车时间为 ,其中 。
2. 前缀和优化
计算 可以优化:
$$\sum_{k=l}^{r} (T - t_k) = (r-l+1) \cdot T - \sum_{k=l}^{r} t_k $$使用前缀和可以在 时间内计算。
3. 完整的状态转移
设 为前 个同学到达时间的前缀和,则:
$$dp[i] = \min_{0 \leq j < i} \left\{ dp[j] + (i-j) \cdot T - (pre[i] - pre[j]) \right\} $$其中 ,
关键洞察
1. 发车时间决策
对于一班载着 区间同学的车:
- 最早发车时间:
- 但为了衔接前一班车,可能需要延迟
- 实际上,发车时间可以取 ()中的任意值
2. 等待时间的计算技巧
等待时间可以重新表述为:
$$\text{等待时间} = \text{发车时间} \times \text{人数} - \text{到达时间之和} $$这使我们能够使用前缀和快速计算。
复杂度分析
- 状态数:
- 转移枚举:
- 时间选择:
- 总复杂度:
对于 ,,计算量约为 ,可以接受。
边界情况处理
- 第一班车:没有前序约束,发车时间就是最后一个同学的到达时间
- 空区间: 表示第 个同学单独一班车
- 时间衔接:确保后一班车不早于前一班车返回时间
算法步骤总结
-
预处理:
- 将同学按到达时间排序
- 计算到达时间的前缀和数组
-
动态规划:
- 初始化
- 对于每个 ,枚举所有可能的
- 对于每个 对,枚举可能的发车时间偏移
- 计算该方案下的等待时间,更新
-
答案提取:
- 答案就是
总结
这道题的核心在于将复杂的调度问题转化为区间划分问题:
- 问题转化:将同学分组,每组乘同一班车
- 状态设计:以"某班车的最后一名乘客"作为状态
- 等待计算:利用前缀和快速计算区间等待时间
- 时间决策:发车时间只需在有限范围内枚举
通过合理的状态设计和数学优化,我们可以在多项式时间内解决这个看似复杂的调度问题。这种"区间划分 + 前缀和优化"的思路在许多优化问题中都有应用。
- 1
信息
- ID
- 5234
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 1
- 上传者