1 条题解
-
0
1. 题意整理
卡组有 张牌:
- 张强化牌,数值
- 张攻击牌,数值
随机抽 张牌(等概率 种可能)。 能打出最多 张牌()。 策略是最大化伤害。
强化牌的效果:如果打出,则之后所有攻击牌伤害都会乘以这张强化牌的数字。 强化牌的效果是乘算,并且打出多张强化牌时效果累乘(比如先打 再打 ,则攻击牌伤害乘以 )。
攻击牌直接造成当前数值的伤害(当前数值已经乘上了之前打出的所有强化牌的乘积)。
问:期望伤害 对 取模的值(即所有可能的抽牌方案的伤害总和)。
等价于:计算所有 种抽牌方案的伤害总和。
2. 最优策略分析
假设抽到 张强化牌, 张攻击牌()。
强化牌数值从大到小排 , 攻击牌数值从大到小排 。
2.1 如何最大化伤害?
强化牌的效果是乘法,且强化牌数值 ,所以越早打出越能放大后续攻击牌的伤害。
所以最优策略是:先把强化牌全部打光(按数值从大到小打,因为乘法交换律其实与顺序无关,但从大到小在 DP 设计中更方便),再打攻击牌。
但如果强化牌太多,可能占满 次出牌机会,那就打不了攻击牌,伤害为 0(因为没有攻击牌打出)。设我们打出 张强化牌(),那么剩下 张牌从攻击牌里选最大的打出。
为什么选最大的?
因为剩下的攻击牌数值 ,打越大的伤害越高。所以最优策略:
- 先选 张强化牌(数值最大的 张强化牌)打出( 吗?注意如果 ,那么没有攻击牌打出,伤害为 0,除非 则伤害 0 一样,所以尽量 不超过 且 才能有攻击牌)。 但 可以等于 ,然后 张攻击牌,但 可能 ,则打不出攻击牌,伤害 0。 所以最优 要尽量让 且 才可打出攻击牌。
总结最优策略枚举: 从 到 (因为必须至少打 1 张攻击牌才有伤害,除非 ,但 时伤害为 0,忽略不计)。
如果 则只能打出 张攻击牌(即所有攻击牌都打出),即实际打出攻击牌数为 。
令 ,则这 张攻击牌选最大的 张。
伤害公式: [ \text{damage} = \left(\prod_{j=1}^{t} a'{(j)}\right) \times \sum{j=1}^{p} b'_{(j)} ] 其中 是选出的 张最大强化牌的数值乘积, 是选出的 张最大攻击牌的数值和。
3. 问题转化为计数问题
我们需要对 所有 抽牌方案,计算这个最大伤害的和。
因为 (),可以 O(n²) DP。
3.1 分别对强化牌和攻击牌排序
设强化牌原数组 从大到小排序,攻击牌 从大到小排序。
3.2 DP 设计
我们想固定 和 (抽到的强化牌和攻击牌的数量),计算所有 种抽牌方案的伤害总和。
但是直接枚举 再枚举 很麻烦。可以换个角度:
考虑最后打出的 张牌的最优构成:
- 可能打出 张强化牌和 张攻击牌( 保证至少一张攻击牌)。
- 强化牌必然是抽到的强化牌中最大的 张(按数值从大到小打,与顺序无关),攻击牌必然是抽到的攻击牌中最大的 张。
因此,我们其实在枚举“最终使用的牌”,然后看有多少种抽牌方案能支持这种“最终使用牌”成为最优方案。
这等价于: 最终使用 张强化牌(指定是哪 张,数值最大的那些)和 张攻击牌(指定是哪 张,数值最大的那些), 那么抽牌方案必须包含这 张牌,并且剩下的 张牌必须从“不被使用”的牌中选,并且不能出现会使得更优策略改变的情况(即不能让某个未被使用的强化牌数值大于已使用的强化牌,否则会替换它?等等)。
这样变得很复杂。换标准做法:
3.3 已知套路解法
这类问题常见解法是:
- 对强化牌和攻击牌分别从大到小排序。
- 分别 DP 出:选出若干强化牌,乘积和;选出若干攻击牌,和的和。
- 然后合并。
定义:
- :从前 张强化牌中选 张强化牌的 所有方案的乘积的和(注意这里是所有方案的乘积的和,不是最大值的和)。
- :从前 张攻击牌中选 张攻击牌的 所有方案的和的和(即所有选出 张的攻击牌数值的总和)。
转移: [ 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) ] 因为选 张包含 的方案数是 ,每种方案里 贡献 ,所以加 。
边界:,注意 。
3.4 合并计算答案
对于固定 :
-
强化牌:我们选出 张最终打出()。
- 这 张必须是抽到的强化牌中最大的 张,但因为我们从大到小排序后 DP 的 是任意选的乘积和,不是“最大 张”的和。
- 需要修正:如果我们决定最终打出 张强化牌,它们必然是抽到的强化牌里最大的 张,所以我们可以先确定这 张是全局最大 张强化牌(即 ),然后剩下的 张强化牌从 到 中选。
所以固定 时: 设 = 从 中选 张的乘积和(其实只有全选,所以是 一种方案,乘积固定)
不对,这里“最大 张”必须是抽到的强化牌里最大的 张,我们枚举 ,实际上我们选 张最大强化牌就是 全要,所以乘积固定为 。那么抽牌方案数:强化牌部分:必须包含 ,再从剩下的 张强化牌中选 张,方案数 。
攻击牌部分:我们要选 张最大攻击牌,设为 ,则必须包含它们,再从剩下的 张攻击牌中选 张,方案数 。
伤害贡献: [ S_t \times (b_1+\dots+b_p) ] 乘以方案数 。
但是这样只是“这种抽牌方案下最优策略的伤害”,我们要对所有 求和。
3.5 换一种更直接的 DP 合并
已知标准题解思路(NOI 2018 模拟赛题):
设 表示从最大的 张强化牌中选 张且必选第 张的乘积和(即最后一张是 )的方案乘积和,但更常用的是:
令 表示从前 张强化牌中选 张的所有方案乘积和(就是我们前面那个 )。
令 表示从前 张攻击牌中选 张的所有方案的和的和(就是我们前面那个 )。
最终答案: 枚举 (打出强化牌数,,且 因为至少要一张攻击牌打出),枚举 满足 ,其中 ,但 是变化的,不好直接枚举。
但可以这样: [ \text{Ans} = \sum_{t=0}^{\min(k-1, m-1)} \left[ \binom{n}{t} \text{??} \right] ] 实际上要分开强化牌和攻击牌的贡献。
最终标答做法简述(根据常见题解):
- 对强化牌从大到小排序,攻击牌从大到小排序。
- 设 表示从前 张强化牌中选 张的所有方案的乘积的和。
- 设 表示从前 张攻击牌中选 张的所有方案的伤害和(即所有方案的攻击牌数值和的总和)。
- 答案 = $\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) ] 再调整组合数为抽到 张强化牌和 张攻击牌且这些牌是最大的那些,剩下的 张从剩下的牌中选。
4. 总结算法步骤
- 输入 ,输入强化牌数组 和攻击牌数组 。
- 对 从大到小排序,对 从大到小排序。
- DP 计算 (强化牌选 张的乘积和)和 (攻击牌选 张的和的和)。
- 预处理组合数 对 取模。
- 枚举 (强化牌打出张数),(攻击牌打出张数),满足 等条件,用组合数计算抽牌方案数,乘上 贡献答案。
- 输出答案。
这样总复杂度 ,可过 。
最终答案就是上述 Ans,已经乘了 ,直接输出即可。
- 1
信息
- ID
- 6160
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者