CF1986E Beautiful Array 题解
Part1. 题目概述
你有一个数组,其顺序可以随意打乱。
你可以在其中任选一个数增加 ,这记为一次操作。
求最小的操作次数以使原数组为回文串。
若不可能,输出 。
Part2. 思路
-
首先看到只能增加 ,说明无论怎么操作,每个数除以 的余数不变。
-
要求得到回文串且顺序可以随意打乱,也就是说只要满足最终的数组只有不大于一个数出现的次数为奇数(这个数拿一个放中间,其他的左右两边对称放)。
-
再回到1,除以 的余数不变,那么可以对除以 的每一个余数分组,每一组都可以通过加 使得数字相等,比如这组样例的分组:
1
213 3
2 3 9 14 17 10 22 20 18 30 1 4 28余数为 余数为 余数为 -
如何判断是否可行呢?只需要统计所有组中有几组的元素个数为奇数(如上面的分组中余数为 组就是奇数个数,必须把这个组中的某个元素放到新序列的中心位置),如果个数大于 ,就一定是不可行的(不可能把多个元素放到中心)。
-
接下来开始构造最优解。可以很清楚地发现,要在每一组中构造出相等的元素对(一个放前面,一个放后面),比如上余数为 组可以这样构造:
只要:
进行了 次操作。
如果是奇数个元素的组,只需要取出一个元素放在中心后,变成偶数个元素的组即可。
-
如何使解最优呢?可以先尝试把每一个组内排个序:
余数为 余数为 余数为 这时候要分类讨论一下了:
-
一组中有偶数个元素。
从小到大,每次取两个,一定最优。(否则如果跨过中间的元素找,一定会需要更多操作,你可以自己模拟一下)。
-
一组中有奇数个元素。
很快想到朴素方法:枚举要去除的元素,求出去除每个元素下的最优,时间复杂度 。
这显然会超时,但大致思路是可行的,求出下一个解时很多计算是和上一个重复的,这就有了优化的方法。下图七个数的情况:
不取 第一组 第二组 第三组 红色的就是变化的部分,这样就解出了(分奇偶讨论一下)。
问题解决!
-
Part3. Code
注意数据范围,存余数等可以开映射解决,也可以离散化。
1 |
|
CF1986E Beautiful Array 题解
http://shicj.pages.dev/2024/07/08/CF1986E Beautiful Array 题解/