1 条题解
-
0
E. 水母与五月花号 详细题解
问题重述
我们有一个 个顶点、 条边的有向无环图(DAG),所有边 满足 。
- 每个顶点 有一个商人,可以无限次购买价格为 、威力为 的卡牌。
- 从顶点 出发,带 枚初始金币,沿着有向边走到目标顶点 。
- 只能在当前所在顶点购买卡牌。
- 目标:最大化购买的卡牌威力总和。
需要回答 个询问,每个询问给定目标顶点 和初始金币 。
关键观察
引理 1
考虑从 到 的任意一条路径 。设 是该路径上 最大的顶点(即性价比最高的顶点),记 ,。
引理: 存在一个最优解,其中从其他顶点购买的卡牌(称为特殊卡牌)数量不超过 张。
证明思路:
- 设特殊卡牌的成本序列为 ,前缀和为 。
- 根据鸽巢原理, 个前缀和模 必有两个相等。
- 这两个相等前缀和之间的卡牌总成本是 的倍数,可以用若干张 点的卡牌替换。
- 由于 的性价比最高,替换后答案不会变差。
推论: 特殊卡牌的总成本不超过 。
核心思想
将问题分成两部分:
- 小 情况():直接 DP
- 大 情况():利用引理,枚举最优性价比顶点
第一部分:小 情况的 DP
定义:
$$f(u, x) = \text{当前在顶点 } u \text{,总花费为 } x \text{ 时的最大威力总和} $$转移:
- 购买卡牌:
- 沿着边移动:,其中 有边
初始化:,其余为 。
复杂度:,由于 ,,可行。
查询时直接输出 。
第二部分:大 情况的 DP
当 时,根据引理,我们可以:
- 枚举每个顶点 作为性价比最高的顶点
- 假设在顶点 购买 张卡牌( 可能为负,表示用其他卡牌替换)
定义:
$$g(i, u, x, 0/1) = \text{当前在顶点 } u \text{,性价比最高顶点为 } i \text{,当前花费模 } c_i \text{ 余 } x \text{,是否已经到达过顶点 } i \text{ 时的最大威力} $$关键技巧:当花费达到 时,立即用一张 点的卡牌替换,使得花费模 始终小于 。
具体实现:
- 记 ,
- 对于顶点 本身:当 时,
- 对于其他顶点 :
- 如果 ,则该顶点不可能出现在最优路径中(因为 是性价比最高的)
- 否则,考虑在 点购买卡牌后的转移:$$g(i, u, (x + c_u) \bmod a, 0/1) = \max(\dots, g(i, u, x, 0/1) + w_u - \left\lfloor\frac{x + c_u}{a}\right\rfloor \cdot b) $$
- 移动转移:$g(i, v, x, 0/1) = \max(g(i, v, x, 0/1), g(i, u, x, 0/1))$
复杂度:,因为 只取 到 。
查询时:
$$\text{ans} = \max_{i=1}^n \left( g(i, p, r \bmod c_i, 1) + \left\lfloor\frac{r}{c_i}\right\rfloor \cdot w_i \right) $$其中 表示必须经过顶点 (因为 是性价比最高的顶点)。
算法流程
-
预处理:
- 计算
- 运行小 DP:
- 运行大 DP:
-
处理查询:
- 若 :输出
- 否则:枚举 ,计算最大值并输出
时间复杂度
- 预处理:
- 每次查询:
- 总复杂度:$O(m \cdot \max(c)^2 + m \cdot n \cdot \max(c) + q \cdot n)$
由于 ,,,,该复杂度可行。
空间复杂度
- 数组:$O(n \cdot \max(c)^2) \approx 200 \times 40000 = 8 \times 10^6$
- 数组:$O(n \cdot n \cdot \max(c) \cdot 2) \approx 200 \times 200 \times 200 \times 2 = 1.6 \times 10^7$
- 均在内存限制内。
代码实现要点
- 使用 初始化 DP 数组(代码中用
0xcfcfcfcfcfcfcfcf) - 对于大 DP,利用周期性优化(根据 分组)
- 注意处理未到达顶点 的情况( 标记)
- 使用
long long存储威力值(可达 )
总结
本题的核心在于:
- 引理:最优解中特殊卡牌数量有限
- 分治:将 的大小分成两种情况处理
- 模运算优化:利用模 的余数进行状态压缩
- 枚举性价比最高点:大 时枚举所有可能的
这种将问题分解成两个子问题的方法,使得原本 的复杂度降到了可接受范围。
- 1
信息
- ID
- 7197
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者