1 条题解
-
0
题目大意
有 (n) 个男孩和 (m) 个女孩,要排成一排,使得任意连续的一段中,男孩与女孩的人数差不超过 (k)。
求方案数对 (12345678) 取模的结果。数据范围:(n, m \leq 150,\ k \leq 20)。
思路分析
1. 条件转化
“任意连续的一段”男女差不超过 (k),等价于所有前缀的男女差不超过 (k),并且所有后缀的男女差也不超过 (k)。
更简单的等价条件是:所有前缀的男女差在 ([-k, k]) 之间,因为任意连续段可以表示为两个前缀之差。
2. 动态规划设计
设
[ dp[i][j][x] ] 表示已经安排了 (i) 个男孩和 (j) 个女孩,且当前前缀的男孩比女孩多 (x) 个((x) 可以为负数,我们加一个偏移量 (k) 变成非负下标 (0 \sim 2k))。- 当 (x = 0) 时,男女数相等。
- 当 (x > 0) 时,男孩比女孩多 (x) 个。
- 当 (x < 0) 时,女孩比男孩多 (|x|) 个。
为了处理负数,我们定义: [ dp[i][j][d] \quad (0 \le d \le 2k) ] 其中 (d) 表示 (男孩数 - 女孩数) + (k),所以实际男女差范围是 ([-k, k]) 对应 (d \in [0, 2k])。
3. 状态转移
-
如果下一个位置放男孩:
- 新差值 (d' = d + 1)(因为男孩数+1,差值增加 1)
- 需要保证新差值对应的实际男女差不超过 (k),即 (d' - k \le k \Rightarrow d' \le 2k) 自然成立(因为 (d \le 2k-1) 时 (d' \le 2k)),但还要保证差值不能低于 (-k)(即 (d' \ge 0)),这里 (d \ge 0) 时加 1 不会低于 0。
- 所以转移为: [ dp[i+1][j][d+1] \ += dp[i][j][d] \quad (d < 2k) ]
-
如果下一个位置放女孩:
- 新差值 (d' = d - 1)
- 需要保证 (d' \ge 0) 且实际男女差不超过 (k)(自动满足,因为 (d' \le 2k) 成立)。
- 所以转移为: [ dp[i][j+1][d-1] \ += dp[i][j][d] \quad (d > 0) ]
4. 初始状态与最终答案
初始状态:
[ dp[0][0][k] = 1 ] 表示 0 个男孩、0 个女孩,差值为 0(偏移后为 (k)),方案数为 1。最终答案:
[ \sum_{d=0}^{2k} dp[n][m][d] ] 即所有男孩女孩都排完,且过程中差值始终合法的方案数之和。
5. 复杂度分析
状态数:(O(n \times m \times (2k+1)))
代入 (n, m \leq 150,\ k \leq 20),约为 (150 \times 150 \times 41 \approx 9 \times 10^5),可以接受。
总结
这道题的核心在于将“任意连续段”的限制转化为对前缀差值的控制,并利用动态规划在状态中记录当前男女差值,从而保证所有中间状态都满足题目要求。
这是一个典型的计数类 DP 问题,考察对状态设计的掌握和条件转化的能力。
- 1
信息
- ID
- 3851
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者