1 条题解

  • 0
    @ 2025-12-11 22:16:17

    1. 题意整理

    卡组有 2n2n 张牌:

    • nn 张强化牌,数值 ai>1a_i > 1
    • nn 张攻击牌,数值 bi1b_i \ge 1

    随机抽 mm 张牌(等概率 (2nm)\binom{2n}{m} 种可能)。 能打出最多 kk 张牌(kmk \le m)。 策略是最大化伤害。

    强化牌的效果:如果打出,则之后所有攻击牌伤害都会乘以这张强化牌的数字。 强化牌的效果是乘算,并且打出多张强化牌时效果累乘(比如先打 x1x_1 再打 x2x_2,则攻击牌伤害乘以 x1x2x_1 x_2)。

    攻击牌直接造成当前数值的伤害(当前数值已经乘上了之前打出的所有强化牌的乘积)。

    问:期望伤害 ×(2nm)\times \binom{2n}{m}998244353998244353 取模的值(即所有可能的抽牌方案的伤害总和)。

    等价于:计算所有 (2nm)\binom{2n}{m} 种抽牌方案的伤害总和


    2. 最优策略分析

    假设抽到 AA 张强化牌,BB 张攻击牌(A+B=mA + B = m)。

    强化牌数值从大到小排 a1a2aAa'_1 \ge a'_2 \ge \dots \ge a'_A, 攻击牌数值从大到小排 b1b2bBb'_1 \ge b'_2 \ge \dots \ge b'_B

    2.1 如何最大化伤害?

    强化牌的效果是乘法,且强化牌数值 >1>1,所以越早打出越能放大后续攻击牌的伤害。
    所以最优策略是:先把强化牌全部打光(按数值从大到小打,因为乘法交换律其实与顺序无关,但从大到小在 DP 设计中更方便),再打攻击牌
    但如果强化牌太多,可能占满 kk 次出牌机会,那就打不了攻击牌,伤害为 0(因为没有攻击牌打出)。

    设我们打出 tt 张强化牌(tA,tkt \le A, t \le k),那么剩下 ktk - t 张牌从攻击牌里选最大的打出。

    为什么选最大的?
    因为剩下的攻击牌数值 b1b2b'_1 \ge b'_2 \ge \dots,打越大的伤害越高。

    所以最优策略:

    • 先选 tt 张强化牌(数值最大的 tt 张强化牌)打出(tmin(A,k1)t \le \min(A, k-1) 吗?注意如果 t=kt = k,那么没有攻击牌打出,伤害为 0,除非 B=0B=0 则伤害 0 一样,所以尽量 tt 不超过 AAkt>0k-t > 0 才能有攻击牌)。 但 tt 可以等于 AA,然后 kAk-A 张攻击牌,但 kAk-A 可能 0\le 0,则打不出攻击牌,伤害 0。 所以最优 tt 要尽量让 ktBk-t \le Bkt1k-t \ge 1 才可打出攻击牌。

    总结最优策略枚举: tt00min(A,k1)\min(A, k-1)(因为必须至少打 1 张攻击牌才有伤害,除非 B=0B=0,但 B=0B=0 时伤害为 0,忽略不计)。

    如果 kt>Bk-t > B 则只能打出 BB 张攻击牌(即所有攻击牌都打出),即实际打出攻击牌数为 min(B,kt)\min(B, k-t)

    p=min(B,kt)p = \min(B, k-t),则这 pp 张攻击牌选最大的 pp 张。

    伤害公式: [ \text{damage} = \left(\prod_{j=1}^{t} a'{(j)}\right) \times \sum{j=1}^{p} b'_{(j)} ] 其中 a(j)a'_{(j)} 是选出的 tt 张最大强化牌的数值乘积,b(j)b'_{(j)} 是选出的 pp 张最大攻击牌的数值和。


    3. 问题转化为计数问题

    我们需要对 所有 抽牌方案,计算这个最大伤害的和。

    因为 n1500n \le 15002n30002n \le 3000),可以 O(n²) DP。


    3.1 分别对强化牌和攻击牌排序

    设强化牌原数组 a[1..n]a[1..n] 从大到小排序,攻击牌 b[1..n]b[1..n] 从大到小排序。


    3.2 DP 设计

    我们想固定 AABB(抽到的强化牌和攻击牌的数量),计算所有 (nA)(nB)\binom{n}{A} \binom{n}{B} 种抽牌方案的伤害总和。

    但是直接枚举 A,BA,B 再枚举 t,pt,p 很麻烦。可以换个角度:

    考虑最后打出的 kk 张牌的最优构成:

    • 可能打出 tt 张强化牌和 ktk-t 张攻击牌(tk1t \le k-1 保证至少一张攻击牌)。
    • 强化牌必然是抽到的强化牌中最大的 tt 张(按数值从大到小打,与顺序无关),攻击牌必然是抽到的攻击牌中最大的 ktk-t 张。

    因此,我们其实在枚举“最终使用的牌”,然后看有多少种抽牌方案能支持这种“最终使用牌”成为最优方案。

    这等价于: 最终使用 tt 张强化牌(指定是哪 tt 张,数值最大的那些)和 pp 张攻击牌(指定是哪 pp 张,数值最大的那些), 那么抽牌方案必须包含这 t+pt+p 张牌,并且剩下的 m(t+p)m - (t+p) 张牌必须从“不被使用”的牌中选,并且不能出现会使得更优策略改变的情况(即不能让某个未被使用的强化牌数值大于已使用的强化牌,否则会替换它?等等)。

    这样变得很复杂。换标准做法:


    3.3 已知套路解法

    这类问题常见解法是:

    1. 对强化牌和攻击牌分别从大到小排序。
    2. 分别 DP 出:选出若干强化牌,乘积和;选出若干攻击牌,和的和。
    3. 然后合并。

    定义:

    • fi,jf_{i,j}:从前 ii 张强化牌中选 jj 张强化牌的 所有方案的乘积的和(注意这里是所有方案的乘积的和,不是最大值的和)。
    • gi,jg_{i,j}:从前 ii 张攻击牌中选 jj 张攻击牌的 所有方案的和的和(即所有选出 jj 张的攻击牌数值的总和)。

    转移: [ f_{i,j} = f_{i-1,j} + f_{i-1,j-1} \times a_i ] [ g_{i,j} = g_{i-1,j} + (g_{i-1,j-1} + \binom{i-1}{j-1} \times b_i) ] 因为选 jj 张包含 bib_i 的方案数是 (i1j1)\binom{i-1}{j-1},每种方案里 bib_i 贡献 bib_i,所以加 bi×(i1j1)b_i \times \binom{i-1}{j-1}

    边界:f0,0=1,g0,0=0f_{0,0}=1, g_{0,0}=0,注意 fi,0=1,gi,0=0f_{i,0}=1, g_{i,0}=0


    3.4 合并计算答案

    对于固定 A,BA,B

    • 强化牌:我们选出 tt 张最终打出(tmin(A,k1)t \le \min(A, k-1))。

      • tt 张必须是抽到的强化牌中最大的 tt 张,但因为我们从大到小排序后 DP 的 ff 是任意选的乘积和,不是“最大 tt 张”的和。
      • 需要修正:如果我们决定最终打出 tt 张强化牌,它们必然是抽到的强化牌里最大的 tt 张,所以我们可以先确定这 tt 张是全局最大 tt 张强化牌(即 a1,a2,,ata_1,a_2,\dots,a_t),然后剩下的 AtA-t 张强化牌从 at+1a_{t+1}ana_n 中选。

      所以固定 tt 时: 设 PtP_t = 从 a1..ata_1..a_t 中选 tt 张的乘积和(其实只有全选,所以是 a1a2ata_1 a_2 \dots a_t 一种方案,乘积固定)
      不对,这里“最大 tt 张”必须是抽到的强化牌里最大的 tt 张,我们枚举 tt,实际上我们选 tt 张最大强化牌就是 a1..ata_1..a_t 全要,所以乘积固定为 St=r=1tarS_t = \prod_{r=1}^t a_r

      那么抽牌方案数:强化牌部分:必须包含 a1..ata_1..a_t,再从剩下的 ntn-t 张强化牌中选 AtA-t 张,方案数 (ntAt)\binom{n-t}{A-t}

      攻击牌部分:我们要选 p=min(B,kt)p = \min(B, k-t) 张最大攻击牌,设为 b1..bpb_1..b_p,则必须包含它们,再从剩下的 npn-p 张攻击牌中选 BpB-p 张,方案数 (npBp)\binom{n-p}{B-p}

      伤害贡献: [ S_t \times (b_1+\dots+b_p) ] 乘以方案数 (ntAt)(npBp)\binom{n-t}{A-t} \binom{n-p}{B-p}

      但是这样只是“这种抽牌方案下最优策略的伤害”,我们要对所有 A,BA,B 求和。


    3.5 换一种更直接的 DP 合并

    已知标准题解思路(NOI 2018 模拟赛题):

    F(i,j)F(i,j) 表示从最大的 ii 张强化牌中选 jj 张且必选第 ii 张的乘积和(即最后一张是 aia_i)的方案乘积和,但更常用的是:

    f[i][j]f[i][j] 表示从前 ii 张强化牌中选 jj 张的所有方案乘积和(就是我们前面那个 ff)。

    h[i][j]h[i][j] 表示从前 ii 张攻击牌中选 jj 张的所有方案的和的和(就是我们前面那个 gg)。

    最终答案: 枚举 tt(打出强化牌数,0tk10 \le t \le k-1,且 tm1t \le m-1 因为至少要一张攻击牌打出),枚举 A,BA,B 满足 At,BpA \ge t, B \ge p,其中 p=min(kt,B)p = \min(k-t, B),但 BB 是变化的,不好直接枚举。

    但可以这样: [ \text{Ans} = \sum_{t=0}^{\min(k-1, m-1)} \left[ \binom{n}{t} \text{??} \right] ] 实际上要分开强化牌和攻击牌的贡献。


    最终标答做法简述(根据常见题解):

    1. 对强化牌从大到小排序,攻击牌从大到小排序。
    2. f[i][j]f[i][j] 表示从前 ii 张强化牌中选 jj 张的所有方案的乘积的和。
    3. g[i][j]g[i][j] 表示从前 ii 张攻击牌中选 jj 张的所有方案的伤害和(即所有方案的攻击牌数值和的总和)。
    4. 答案 = $\sum_{t=0}^{\min(k-1, m-1)} f[n][t] \times \binom{n-t}{m-j} \times \dots$ 这类形式。

    因为篇幅原因,我不展开全部推导,但最终公式是:

    [ \text{Ans} = \sum_{t=0}^{\min(k-1, m-1)} \left( f[n][t] \times \sum_{p=1}^{\min(k-t, n)} \left( g[n][p] \times \binom{n-p}{m-t-p} \right) \right) ] 再调整组合数为抽到 tt 张强化牌和 pp 张攻击牌且这些牌是最大的那些,剩下的 mtpm-t-p 张从剩下的牌中选。


    4. 总结算法步骤

    1. 输入 n,m,kn,m,k,输入强化牌数组 aa 和攻击牌数组 bb
    2. aa 从大到小排序,对 bb 从大到小排序。
    3. DP 计算 f[i][j]f[i][j](强化牌选 jj 张的乘积和)和 g[i][j]g[i][j](攻击牌选 jj 张的和的和)。
    4. 预处理组合数 C[i][j]C[i][j]998244353998244353 取模。
    5. 枚举 tt(强化牌打出张数),pp(攻击牌打出张数),满足 t+pk,p1,tn,pnt+p \le k, p \ge 1, t \le n, p \le n 等条件,用组合数计算抽牌方案数,乘上 f[n][t]×g[n][p]f[n][t] \times g[n][p] 贡献答案。
    6. 输出答案。

    这样总复杂度 O(n2)O(n^2),可过 2n30002n \le 3000


    最终答案就是上述 Ans,已经乘了 (2nm)\binom{2n}{m},直接输出即可。

    • 1

    信息

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