1 条题解

  • 0
    @ 2025-10-20 10:08:29

    问题分析

    本题是一道基于动态规划(DP)的状态转移问题,核心是处理具有时间限制的"空位填补"约束。通过分析代码可知,问题需要计算在n+mn+m个回合中,满足特定空位填补规则的合法序列数量,其中空位必须在产生后的KK个回合内被填补。

    算法思路

    1. 状态定义

    使用二维DP数组dp[t][j]表示状态,其中:

    • tt 是当前回合的奇偶标记(用于空间优化,交替使用两个状态数组)
    • jj 是一个KK位二进制掩码(mask),第ii位为11表示存在一个空位需要在接下来的i+1i+1个回合内被填补

    掩码的意义:例如当K=3K=3时,掩码101表示:

    • 00位为11:有一个空位需在11回合内填补
    • 22位为11:有一个空位需在33回合内填补

    2. 状态转移

    对于每个回合ii(从n+1n+1n+mn+m),根据当前掩码jj的最高位是否为11分两种情况处理:

    (1)最高位为00!((j >> K - 1) & 1)

    此时没有即将过期的空位,状态转移包含两部分:

    • 填补已有空位:选择填补掩码中任意一个空位(对应掩码中的11),转移公式为:

      $$\sum_{k \in \text{set bits of } j} dp[t \oplus 1][(j \ll 1) \oplus (k \& -k)] $$

      其中k & -k用于提取kk的最低位11,实现对单个空位的填补操作。

    • 不填补空位,新增空位:直接将掩码左移一位(时间推进),并计算新增空位的贡献:

      $$dp[t \oplus 1][j \ll 1] \times ((i + \text{popcount}(j) \times 2) - 3) $$

      其中popcount(j)\text{popcount}(j)是掩码jj11的个数(当前空位数量)。

      总转移公式:

      $$dp[t][j] = \left( \sum + dp[t \oplus 1][j \ll 1] \times ((i + \text{popcount}(j) \times 2) - 3) \right) \mod \text{mod} $$

    (2)最高位为11(j >> K - 1) & 1

    此时存在即将过期的空位(必须在本回合填补),转移公式为:

    $$dp[t][j] = dp[t \oplus 1][(j \ll 1) \& \text{mask}] \times (i + \text{popcount}(j) - 3) \mod \text{mod} $$

    其中mask = (1 << K) - 1,用于确保左移后仍为KK位掩码。

    3. 初始状态与边界

    • 初始状态:dp[0][0] = 1(第00回合,无空位时只有11种合法状态)
    • 空间优化:使用两个KK位掩码数组交替存储状态(t ^ 1表示上一回合)
    • 最终答案:经过mm个回合后,无空位的状态数量dp[m & 1][0]m & 1获取最后一个回合的奇偶标记)

    关键公式与复杂度

    1. 掩码运算

      • 左移操作:j << 1(时间推进,所有空位的剩余时间减11
      • 掩码截取:(j << 1) & mask(确保结果为KK位)
      • 空位填补:(j << 1) ^ (k & -k)(清除特定空位)
    2. 组合数计算

      • 新增空位的选择数:(i + popcount(j) × 2) - 3
      • 强制填补的选择数:(i + popcount(j) - 3)
    3. 时间复杂度

      • 每个回合需要处理2K2^K个掩码状态
      • 每个状态的转移需要遍历掩码中11的个数(最多KK个)
      • 总复杂度:O(m×2K×K)O(m \times 2^K \times K),其中mm是回合数,KK是最大时间限制(代码中K10K \leq 10,因此2K10242^K \leq 1024
    • 1

    信息

    ID
    3097
    时间
    500ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    11
    已通过
    1
    上传者