火柴排队
这道题目看到题干就知道跟逆序对相关了
首先考虑最终的等式会是怎么样的
既然要成为同序和,我们将两个序列中值相同的连边,比如
那么最终我们要让所有边都是竖直的
由于很像逆序对,我们考虑这里的逆序对是什么
不难看出是有交叉,即用一个二元组\((x,y)\)描述一条边,其中\(x\)是\(a\)中的下标,\(y\)是\(b\)中的下标
那么就是序列中存在两个二元组\((x_1,y_1)\)和\((x_2,y_2)\),满足\(x_1<x_2\)且\(y_1>y_2\),那么这就贡献了一个逆序对
首先有逆序对肯定不是最终序列
我们再证明没有逆序对了一定是最终序列
在没有逆序对的序列中,由于不存在逆序对,所以对\((1,y_1)\),\((2,y_2)\),\((3,y_3)\)...\((n,y_n)\),有\(y_n>...>y_3>y_2>y_1\),根据抽屉原理,必有\(y_i=i\),即都是竖直的边,所以就是最终序列
我们再来证明如果一个序列有逆序对,那么一定存在相邻逆序对
反证,如果不存在相邻逆序对,即对\((i,y_i)\)和\((i+1,y_{i+1})\),有\(y_i<y_{i+1}\),那么对\(i\)赋值从\(1\)到\(n-1\),由鸽巢原理可以得出不存在逆序对,与条件矛盾,所以一定有相邻逆序对
我们的一次操作显然最多使逆序对减少一,所以逆序对个数是下限,而我们每次操作相邻逆序对就可以达到这个下限
所以没啥想法可以考虑转换成图论想一想
然后解释一下洛谷题解以\(a\)为关键字对\(b\)排序的意思,这是我复习的时候想出来的
首先我们先证明,任何一种操作方式,如果同时操作了两个序列,设操作此时为\(x\),则都可以找到一种操作方式只操作一个序列,且操作次数仍为\(x\)
我们不妨尝试将对\(a\)的操作全部转移到\(b\)上去
我们考虑最后一次操作\(a\)的操作,假设交换了\(a_i\)和\(a_{i+1}\),如果我们不操作这一次,那么在其他操作都不变的情况下,最后可以交换\(b_i\)和\(b_{i+1}\)来让序列最优,这也就是说这一次对\(a\)的操作可以转化为一次对\(b\)的操作
我们一直这么转换,最后肯定就可以不操作\(a\),只操作\(b\)了
所以我们考虑如何只操作一个数组来达到最优
最优的时候肯定是\(a\)的最大对应\(b\)的最大,\(a\)的次大对应\(b\)的次大,以此类推
那么我们对\(a\),\(b\)进行离散化,以样例二为例
\(a\)就变成了1 3 4 2
\(b\)就变成了1 4 2 3
那么最终我们是要将\(b\)变为1 3 4 2
的,也就是说\(b\)的1
要放到第一个位置,3
要放到第二个位置,4
要放到第三个位置,2
要放到第四个位置(这里从\(a\)可以直接看出来),这里我们就抽象一下,因为\(a\)不变,所以现在就认为\(1\)是传统的\(1\),\(3\)是传统的\(2\),\(4\)是传统的\(3\),\(2\)是传统的\(4\),\(a\)就是下标序列,所以我们再次对\(b\)重新编号,也就是1 3 4 2
(\(a\)也就是\(b\)的下标序列,也就是将\(a\)重新抽象为1 2 3 4
,\(b\)也跟着重新抽象),然后我们要将这个序列通过邻项交换变成有序的,也就是1 2 3 4
,当然就是求逆序对了
这种抽象也告诉了我们一种一般的做法:将一种序列通过相邻交换到另一种序列的最小交换次数