1 条题解

  • 0
    @ 2025-11-9 17:36:49

    题解

    「ROI 2025 Day2 T3」最小化逆序对 题解

    题目分析

    给定 n×mn \times m 矩阵,每次取第一行或第一列,要最小化最终序列的逆序对数。

    算法思路

    1. 问题转化

    将取行和列的过程看作一个路径规划问题:

    • 状态 (i,j)(i, j) 表示已经取了前 ii 行和前 jj
    • (i,j)(i, j) 可以:
      • 取第 i+1i+1 行 → (i+1,j)(i+1, j)
      • 取第 j+1j+1 列 → (i,j+1)(i, j+1)

    2. 关键观察

    取行或列时新增的逆序对只与已取部分和新增部分的相对大小有关,可以预处理。

    3. 算法步骤

    步骤1:矩阵转置

    总是转置使得 nmn \le m,降低复杂度。

    步骤2:计算初始逆序对

    用二维树状数组统计原矩阵中所有逆序对数量。

    步骤3:分块预处理

    • 对行分块,块大小 n\sqrt{n}
    • 预处理 f[i][j]g[i][j]
      • f[i][j]:取第 ii 行时,与前 jj 列已取元素产生的逆序对
      • g[i][j]:取第 jj 列时,与前 ii 行已取元素产生的逆序对

    步骤4:动态规划

    dp[0][0] = 0
    for i = 0 to n
      for j = 0 to m
        dp[i+1][j] = min(dp[i+1][j], dp[i][j] + f[i+1][j])
        dp[i][j+1] = min(dp[i][j+1], dp[i][j] + g[i][j+1])
    

    最终答案 = dp[n][m] + 初始逆序对

    复杂度分析

    • 初始逆序对计算O(nmlognlogm)O(nm \log n \log m)
    • 分块预处理O(nmn)O(nm \sqrt{n})
    • 动态规划O(nm)O(nm)
    • 总复杂度O(nmn)O(nm \sqrt{n}),可处理 nm2×106nm \le 2 \times 10^6 的数据

    算法优势

    1. 转置优化:保证 nn 较小,降低分块和 DP 的复杂度
    2. 分块技巧:平衡预处理和查询的复杂度
    3. 完备性:考虑了所有可能的操作顺序

    总结

    本题通过巧妙的动态规划状态设计,结合分块预处理和二维树状数组,高效解决了矩阵操作顺序的优化问题。算法在保证正确性的同时,能够处理大规模数据输入。

    最终算法标签动态规划 二维树状数组 分块算法 逆序对计数 矩阵转置

    • 1

    信息

    ID
    5114
    时间
    1000ms
    内存
    1000MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者