火柴排队

这道题目看到题干就知道跟逆序对相关了

首先考虑最终的等式会是怎么样的

既然要成为同序和,我们将两个序列中值相同的连边,比如

那么最终我们要让所有边都是竖直的

由于很像逆序对,我们考虑这里的逆序对是什么

不难看出是有交叉,即用一个二元组\((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,当然就是求逆序对了

这种抽象也告诉了我们一种一般的做法:将一种序列通过相邻交换到另一种序列的最小交换次数

posted @ 2023-12-15 21:23  最爱丁珰  阅读(3)  评论(0编辑  收藏  举报