1 条题解

  • 0
    @ 2025-11-9 12:19:10

    题目分析

    这是一个关于保镖在数轴上移动,保护 VIP 并最大化小费的优化问题。主要难点在于:

    1. 时间空间范围巨大:达到 10^9 级别
    2. 查询数量极多:Q 可达 3,000,000
    3. 需要高效处理:不能对每个查询都重新计算

    关键思路

    1. 坐标变换

    将问题从 (时间, 位置) 空间转换到 (时间+位置, 时间-位置) 空间:

    • 对于 VIP i:st = (T_i + A_i, T_i - A_i)ed = (T_i + |B_i - A_i| + B_i, T_i + |B_i - A_i| - B_i)
    • 对于查询 j:(x, y) = (P_j + X_j, P_j - X_j)

    这样转换后,保镖在数轴上的移动就变成了在新坐标系中的移动,且速度限制转化为 45 度方向的移动限制。

    2. 离散化

    由于坐标范围很大但实际用到的点有限(最多 2N 个不同的 x 和 y 坐标),进行离散化处理:

    • 收集所有 VIP 的起点和终点的 x, y 坐标
    • 排序并去重,建立映射关系

    3. 动态规划预处理

    定义 dp[i][j] 表示从离散化后的坐标 (i, j) 出发能获得的最大小费。

    状态转移:

    dp[i][j] = max(
        dp[i+1][j] + wx[i][j] * (bx[i+1] - bx[i]),
        dp[i][j+1] + wy[i][j] * (by[j+1] - by[j])
    )
    

    其中:

    • wx[i][j]:在 x 方向从 i 到 i+1 时,在 y 坐标 j 处能保护的最大 VIP 小费率
    • wy[i][j]:在 y 方向从 j 到 j+1 时,在 x 坐标 i 处能保护的最大 VIP 小费率

    4. 凸包优化

    对于每个查询,我们需要找到最优路径。这可以转化为在凸包上查询最大值的问题:

    • 对于每个离散化的 x 坐标,处理对应的查询
    • 使用凸包技巧快速回答:给定斜率,找到截距最大的直线

    算法流程

    1. 读入数据并转换坐标
    2. 离散化处理
    3. 预处理 wxwy 数组
    4. DP 计算 dp 数组
    5. 处理查询
      • 将查询按离散化后的坐标分组
      • 对每个坐标使用凸包优化回答查询

    复杂度分析

    • 预处理:O(N²) 对于 N ≤ 2800 是可接受的
    • 查询处理:O((N+Q) log N),对于 Q 很大但凸包优化保证了效率

    代码实现要点

    1. 内存优化:使用 vector 动态分配,避免静态数组过大
    2. 边界检查:防止数组越界
    3. 凸包维护:使用单调栈维护上凸壳
    4. 查询回答:二分查找在凸包上找到最优解

    总结

    本题的难点在于:

    • 坐标变换将问题简化
    • 离散化处理大范围数据
    • DP 预处理所有可能状态
    • 凸包优化快速回答大量查询

    通过这种分层处理的方法,将原本看似 O(NQ) 的暴力算法优化到了可接受的范围,是典型的"预处理+优化查询"思路。

    • 1

    信息

    ID
    4962
    时间
    4000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    7
    已通过
    1
    上传者