Loading

Smithing Skill

算法

转化题意,

显然的, 每次操作必定是先锻造再熔毁, 获得 \(2\) 点经验, 并且花费 \(w_i = a_i - b_i\) 个同类型金属, 问题就是说, 如何操作使得操作次数可以最多

首先使用贪心思路, 以 \(w_i\) 为关键字升序排序, 显然的, 在前面的物品一定应该先选择, 并且维护 \(a_i\) 递减, 不递减的都没有用

有一种朴素的方法是, 对于每一种金属, 都贪心的去按照序列顺序选择, 但是这样不够优秀, 考虑优化

首先, 对于每一种材料, 我们按照贪心的去选, 这样一定是最优秀的

但是这样做, 时间复杂度达到了 \(\mathcal{O} (n \log n + nm)\) , 包过不去的, 那么怎么处理呢?

考虑暴力劣在哪里, 对于每一种金属, 我们都枚举了所有材料, 很显然不优

我们考虑对于每一种武器, 直接枚举所有金属, 这样时间复杂度显然更优, 那么如何来处理呢

发现每一种 \(c_i\) 的本质相同, 只是不能混着用, 注意到我们可以预处理 \(c_i\) 值域的最优解, 这样每次就不用重复处理了

我们可以处理出对于所有 \(c_i\) , 当 \(c_i = x\) 时, 最优的 \(w_i\) 为多少, 即 \(\displaystyle \min_{a_j \leq x} a_j - b_j\) , 记为 \(cost_x\)

那么 \(cost_x\) 是好递推的, 我们只需要先用每一种 \(a_j - b_j\) 更新, 然后类似前缀的做一遍, 这算是一种普遍的 \(\rm{trick}\)

考虑令 \(f_x\) 表示当 \(c_i = x\) 时, 最优的锻造方式, 那么显然的, 有

\[f_x = f_{x - cost_x} + 2 \]

每次读入 \(c_i\) 先用最优情况的 \(w_i\) 把它降到 \(10^6\) 级别即可

代码

状态超级差, 真的不想打

总结

本质相同的问题, 优化要利用这点

\(10^8\) 以上的问题, 观察是否真的需要处理这么多

posted @ 2024-12-05 16:15  Yorg  阅读(4)  评论(0编辑  收藏  举报