1 条题解
-
0
问题分析
本题是一道基于动态规划(DP)的状态转移问题,核心是处理具有时间限制的"空位填补"约束。通过分析代码可知,问题需要计算在个回合中,满足特定空位填补规则的合法序列数量,其中空位必须在产生后的个回合内被填补。
算法思路
1. 状态定义
使用二维DP数组
dp[t][j]
表示状态,其中:- 是当前回合的奇偶标记(用于空间优化,交替使用两个状态数组)
- 是一个位二进制掩码(mask),第位为表示存在一个空位需要在接下来的个回合内被填补
掩码的意义:例如当时,掩码
101
表示:- 第位为:有一个空位需在回合内填补
- 第位为:有一个空位需在回合内填补
2. 状态转移
对于每个回合(从到),根据当前掩码的最高位是否为分两种情况处理:
(1)最高位为(
!((j >> K - 1) & 1)
)此时没有即将过期的空位,状态转移包含两部分:
-
填补已有空位:选择填补掩码中任意一个空位(对应掩码中的),转移公式为:
$$\sum_{k \in \text{set bits of } j} dp[t \oplus 1][(j \ll 1) \oplus (k \& -k)] $$其中
k & -k
用于提取的最低位,实现对单个空位的填补操作。 -
不填补空位,新增空位:直接将掩码左移一位(时间推进),并计算新增空位的贡献:
$$dp[t \oplus 1][j \ll 1] \times ((i + \text{popcount}(j) \times 2) - 3) $$其中是掩码中的个数(当前空位数量)。
总转移公式:
$$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)最高位为(
(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
,用于确保左移后仍为位掩码。3. 初始状态与边界
- 初始状态:
dp[0][0] = 1
(第回合,无空位时只有种合法状态) - 空间优化:使用两个位掩码数组交替存储状态(
t ^ 1
表示上一回合) - 最终答案:经过个回合后,无空位的状态数量
dp[m & 1][0]
(m & 1
获取最后一个回合的奇偶标记)
关键公式与复杂度
-
掩码运算:
- 左移操作:
j << 1
(时间推进,所有空位的剩余时间减) - 掩码截取:
(j << 1) & mask
(确保结果为位) - 空位填补:
(j << 1) ^ (k & -k)
(清除特定空位)
- 左移操作:
-
组合数计算:
- 新增空位的选择数:
(i + popcount(j) × 2) - 3
- 强制填补的选择数:
(i + popcount(j) - 3)
- 新增空位的选择数:
-
时间复杂度:
- 每个回合需要处理个掩码状态
- 每个状态的转移需要遍历掩码中的个数(最多个)
- 总复杂度:,其中是回合数,是最大时间限制(代码中,因此)
- 1
信息
- ID
- 3097
- 时间
- 500ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 11
- 已通过
- 1
- 上传者