Codeforces 1148E Earth Wind and Fire

分析

必要条件:
① $\sum_{i=1}^{n} s_i = \sum_{i=1}^{n} t_i$

预处理:
将 $s, t$ 从小到大排序。

尝试一
首尾匹配。例子
s = 2, 2, 4, 7, 9
t = 4, 5, 5, 5, 5

4, 2, 4, 7, 7
4, 4, 4, 7, 5
4, 5, 4, 6, 5
4, 5, 5, 5, 5

反例
s = 1, 4, 5, 8
t = 2, 3, 6, 7

key observation:
考虑排好序的 $s$ 和 $t$。
① 每次操作必然使得某个 $s_i$ 变成某个 $t_j$ 。
② 若有解则一定存在一种操作方法使得最后 s 中的数的相对顺序不变。换言之,最后 $s_1$ 变成 $t_1$,$s_2$ 变成 $t_2$ ……

可以用反证法证明第二个结论。假设存在一开始 $s_i < s_j$ 而最后 $s_i > s_j$,那么考虑使 $s_i < s_j$ 变成 $s_i > s_j$ 的那次操作,假设这次操作是使 $s_i$ 变大,则可以把这次操作拆成两个:先把 $s_i$ 变成 $s_j$,再把 $s_j$ 变成 $s_i$ 的目标值。

于是我们可以把这个问题看成是一种括号匹配问题。
若 $s_i < t_i$ 则把 $t_i - s_i$ 看成“左括号”,若 $s_i > t_i$ 则把 $s_i - t_i$ 看成“右括号”。
若 $s_i < t_i$ 则把二元组 $(t_i - s_i, \text{$s_i$ 原来的下标})$ 放进栈里,遇到“右括号”就将其与栈顶的“左括号”配对,若栈顶的左括号被“耗尽”就将其弹出栈;若栈空了而“右括号”还有剩余则说明无解。

官方题解

代码

猜你喜欢

转载自www.cnblogs.com/Patt/p/11865691.html