1 条题解

  • 0
    @ 2025-10-26 13:35:03

    题目理解

    nn 支队伍参加 ICPC 竞赛,封榜前第 ii 支队伍的过题数为 aia_i

    滚榜时,主办方按照 bib_i 不降 的顺序依次公布每支队伍的封榜后过题数 bib_i,且每次公布后该队伍都会成为当前排行榜的第一名。

    已知所有队伍封榜后总过题数 i=1nbi=m\sum_{i=1}^n b_i = m,求最终排行榜上队伍排名情况的可能数。


    关键观察

    1. 排名规则

    • 按总过题数 ai+bia_i + b_i 从大到小排序
    • 题数相同时,编号小的队伍排名靠前

    2. 公布顺序的限制

    • bib_i 序列必须非递减
    • 每次公布后,当前队伍必须成为第一名

    3. 问题转化

    这实际上是一个状压 DP 计数问题:

    • 状态表示哪些队伍已经公布了 bib_i
    • 需要保证每次新公布的队伍能超过当前第一名

    算法思路

    状态设计

    f[S][i][j]f[S][i][j] 表示:

    • SS:已公布队伍的集合(状态压缩)
    • ii:当前最后公布的队伍编号
    • jj:已使用的 bib_i 总和

    值为达到该状态的方案数。

    状态转移

    从状态 f[S][i][j]f[S][i][j] 出发,枚举下一个公布的队伍 kkkSk \notin S):

    队伍 kk 要成为新的第一名,其 bkb_k 必须满足:

    1. bkbib_k \ge b_ibb 序列非递减)
    2. ak+bkai+bia_k + b_k \ge a_i + b_i(成为第一名)

    实际上可以计算出 bkb_k 的最小值:

    bk=max(bi,ai+biak+[k>i])b_k = \max(b_i, a_i + b_i - a_k + [k > i])

    其中 [k>i][k > i] 是处理编号比较的细节:当题数相同时,编号小的排名靠前。

    初始状态

    对于每个队伍 ii,如果它能成为第一个公布的队伍:

    f[2i1][i][n×g(id,i)]=1f[2^{i-1}][i][n \times g(id, i)] = 1

    其中 idid 是封榜前过题数最多的队伍编号,g(x,y)g(x,y) 是计算 yy 要超过 xx 所需的最小 byb_y

    最终答案

    $$\text{ans} = \sum_{i=1}^n \sum_{j=0}^m f[2^n-1][i][j] $$

    复杂度分析

    • 状态数O(2nnm)O(2^n \cdot n \cdot m)
    • 转移复杂度O(n)O(n)
    • 总复杂度O(2nn2m)O(2^n \cdot n^2 \cdot m)

    对于 n13n \leq 13m500m \leq 500,该算法可以通过。


    算法标签

    • 状态压缩动态规划
    • 计数问题
    • 排列计数

    总结

    本题通过状态压缩 DP 巧妙地处理了滚榜过程中的各种约束条件:

    1. bib_i 的非递减性
    2. 每次公布后当前队伍成为第一名
    3. bib_i 和为 mm

    算法充分利用了 nn 较小的特点,通过状压枚举所有可能的公布顺序,是经典的计数类 DP 问题。

    • 1

    信息

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