P15848 [NOISG 2026 Finals] 饿猫
场上做了两个小时,差点坠机。。。
第一问是简单的,如果 \(f_i \leq f_{n-i+1}\) 那么直接交换它们,直接模拟看最远能走到哪里即可,记最远能走到 \(pos\) 。
做第二问的时候你可能会得出来一个假做法:先一直走,走到不能走的时候交换前面的差值最大的一对。
但实际上这是错的,比如最后一组样例,你要从 \(3\) 走到 \(4\) ,这时候油不够,你选择交换差值最大的两个车站也就是 \(f_3\) 和 \(f_4\) ,但是从 \(4\) 走到 \(5\) 又不够了。这是因为交换 \(f_3\) 和 \(f_4\) 不会使从 \(4\) 出发时油量更多,不如交换\(f_1\) 和 \(f_6\)
于是再进行转化,我们可以预处理没进行交换时,走到每个车站的剩余油量,记为 \(b_i\) 。
交换 \(f_i\) 和\(f_{n-i+1} (i\leq \frac{n}{2})\) 相当于对 \(b_{i+1}\) 到 \(b_{n-i+1}\) 加上 \(f_{n-i+1} - f_i\) ,问最少进行几次操作使得 \(b_1\) 到 \(b_{pos}\) 都大于等于 \(0\) 。
这个直接做还是不好做。但是我们看单个 \(b_i\) ,我们如果想让他大于等于 \(0\) 肯定是在能给他加的区间里选最大的进行操作,那么能给他加的区间是
于是我们会发现限制区间最小的是 \(1\) ,其次是 \(n\) ,然后是 \(2\) ,然后是 \(n-1...\)
所以我们从限制区间小的做到限制区间大的(如果他大于 \(pos\) 就不管他),每次就在他的限制区间里面选最大的,做区间加,然后再把选的位置的值设成负无穷,直到 \(b_i \ge 0\) 了再做下一个限制区间大于等于它的,用一颗线段树维护区间最大值就行了。
感觉这个贪心策略非常不自然啊,还是说我犯糖了这其实是一个经典模型?

浙公网安备 33010602011771号