Loading

[图灵杯 2025] T1. 登机

思路

首先考虑 \(p_i\) 递增的情况
此时任意一个人都要等到他前一个人放完了才能接着走
不难发现最终每个人的用时也可以简单的表示成其前一个人到位的时间和他本来到位的时间取 \(\max\) 然后接着走后一段
这样可以考虑到他和之前的人一起被挡的时间

考虑一般情况
一个人路上可能是会被一车人挡的, 但是我们发现只需要知道最后一个确实挡到他的人即可, 因为后面的速度长度确定

考虑如何计算最后一个挡到他的人, 事实上最后一个挡到 \(i\) 的人 \(x\), 一定要满足 \(p_x < p_i\)\(p_i - p_j + \max(c_j, s_i + p_j)\) 最大
事实上上述柿子可以改写为 \(\max(p_i - p_j + c_j, p_i + s_i)\), 等价于 \(p_i + \max(c_j - p_j, s_i)\)


好的, 考虑拟人一点的做这个题

首先考虑 \(p_i\) 递增的情况
现在, 每个人到达的时间可以表示为

\[c_i = \begin{cases} c_{i - 1} & c_{i - 1} > s_i + p_{i - 1}\\ s_i + p_{i - 1} & \text{otherwise.} \end{cases} + (p_i - p_{i - 1}) \]

表示被前一个人挡住, 然后在走完剩下一段


现在考虑一般情况
上述特殊性质的提示使我们注意到一个关键性质: 我们即使被多个人挡过了, 但是我们总可以归纳成被上一个人挡了之后再走的情况, 因为我们都被挡住了, 那么上一个人一定也一起被挡住了

现在的一般情况下, 还有没有这样的性质?
我们发现不能总视作被上一个人挡了之后再走, 但是我们还是能发现一个性质
即无论如何, 我们总可以归纳成被某个人挡了之后再走

这是为什么?
因为我们跟着之前的人一起被挡, 总是可以视作被只被前面那个人挡了
因此我们要找到 \(j < i, p_j < p_i\)

\[\max \begin{cases} c_j & c_j > s_i + p_j\\ s_i + p_j & \text{otherwise.} \end{cases} + (p_i - p_j) \]

可以视作被其挡住, 然后走完余程


考虑更好理解的做法
按照出发时间依次处理每个人

第一个人显然会在 \([s_1 + p_1, s_1 + p_1 + a_1]\) 时间段占用 \(p_1\), 且只有在这段时间内才有可能影响到后面的入
第二个人, 出发之后可能会在 \(s_2 + p_1 \in / \notin[s_1 + p_1, s_1 + p_1 + a_1]\) 时间段到达 \(p_1\) 并且停下 \(\max(s_1 + a_1 - s_2, 0)\) 的时间, 因而会在 \([\max(s_1 + p_1 + a_1, s_2 + p_1) + p_2 - p_1, \max(s_1 + p_1 + a_1, s_2 + p_1) + p_2 - p_1 + a_2]\) 时间到达并占据 \(p_2\)

第三个人, 他面对的是两个可能挡到它的区间\((\)假设第三个人的目标在前两个之后\()\)
不难发现可以拆分成这样一个问题
\(p_1 \sim [l_1, r_1], p_2 \sim [l_2, r_2]\), 求到达 \(p_3 > p_2 > p_1\) 的时间
不难发现跨过 \(p_1\) 的时间是 \(\max (s_3 + p_1, r_1)\), 在这个基础上, 到达 \(p_2\) 的时间是 \(\max(s_3 + p_1, r_1) + p_2 - p_1\), 跨过 \(p_2\) 的时间是 \(\max \big(\textrm{max}(s_3 + p_1, r_1) + p_2 - p_1, r_2\big)\)

不妨设 \(f_i\) 表示跨过 \(p_i\) 的时间
显然有

\[f_i \gets \max(f_{i - 1} + p_i - p_{i - 1}, r_i) \]

这种形式的是否存在简单解?
也就是

\[f_i \gets \max(f_{i - 1} + c_i, r_i) \]

不难发现

\[f_i = \max_{1 \leq k \leq i} \left( r_k + \sum_{j=k+1}^i c_j \right) = S_i + \max_{1 \leq k \leq i} (r_k - S_k) \]

所以总的来讲, \(f_n = p_n + \max_{1 \leq k \leq n} (r_k - p_k)\), 大赢特赢

因此我们可以快速地对这个东西取 \(\max\) 维护即可


总的来处理一遍

首先, 按照时间顺序处理每一个人
然后, 对于每一个人, 我们知道它需要跨越哪些间隔, 对这些间隔做处理即可, 显然可以扫描一维数据结构维护一维

总结

这种时间出现的问题, 我们可以考虑挨个处理而不是真的去模拟
也就是说, 他们之间的挤压关系, 可以视作是在相同的时间到达了相同的位置, 可以简单处理

形如 \(f_i \gets \max(f_{i - 1} + c_i, r_i)\) 的转移可以快速支持插入
也就是这种在某个点处寻求变化, 每个点的贡献是一定的

尝试考虑 \(\rm{dp}\) 的本质, 进而简化一些操作

posted @ 2025-05-27 20:53  Yorg  阅读(21)  评论(0)    收藏  举报