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\) 时, 最优的锻造方式, 那么显然的, 有
每次读入 \(c_i\) 先用最优情况的 \(w_i\) 把它降到 \(10^6\) 级别即可
写的有点一坨, 重复习一下
题意
个武器, 每个武器有属性 , 表示锻造所需的花费, 熔毁返还的花费
种金属, 每种金属有 个
锻造第 个武器的定义
对于第 种金属, 其当前还剩下 个, 如果 , 可以令
求最多的锻造次数
根据定义不难发现
贪心做法
每一个武器的花费
按照 排序之后, 单调栈维护 递减即可
每一种金属按照排完序之后的顺序依次尽量锻造
复杂度
考虑优化,
不难发现对于每种金属, 处理的本质是相通的, 考虑对于 \(g_i\) 的值域进行 \(\rm{dp}\)
但是该如何处理?
令 \(f_i\) 表示 \(g_i = i\) 时对应的最多锻造次数, 并不好直接做, 考虑辅助数组
令 \(cost_i\) 表示 \(g_i = i\) 时对应的最优 \(w_i\) , 形式的讲就是所有 \(c_i \leq i\) 中 \(\min \{w_i = c_i - p_i \}\)
这个怎么做?
常见处理方式
对于这种求 中的最值
我们可以考虑先赋上单点, 然后扫一遍更新
对于本题, 考虑对于排完序之后的数列, 更新 , 然后倒序扫一遍更新即可
此事在 雅礼国庆集训 day1 T1 养花 亦有记载
搞完这些, \(f_i\) 转移不难得出
也就是说每次都用最优解
最后一个问题是 \(g_i\) 非常巨大, 但是不难发现每次读入 \(c_i\) 先用最优情况的 \(w_i\) 把它降到 \(10^6\) 级别即可
代码
状态超级差, 真的不想打
总结
本质相同的问题, 优化要利用这点
\(10^8\) 以上的问题, 观察是否真的需要处理这么多

浙公网安备 33010602011771号