1 条题解

  • 0
    @ 2025-10-23 8:49:47

    题目大意

    有 (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
    上传者