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\)
这个我不会证明。

② 不考虑操作次数不超过 \(5n\) 的限制。若有解则一定存在一种操作方法使得石头的相对位置不变。换言之,最后 \(s_1\) 变成 \(t_1\)\(s_2\) 变成 \(t_2\)\(s_3\) 变成 \(t_3\) ……

可以用反证法证明第二个结论。假设存在一开始 \(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$ 原来的下标})$ 放进栈里,遇到“右括号”就将其与栈顶的“左括号”配对,若栈顶的左括号被“耗尽”就将其弹出栈;若栈空了而“右括号”还有剩余则说明无解。

官方题解

代码

posted @ 2019-11-15 14:07  Pat  阅读(162)  评论(0编辑  收藏  举报