CF 1654E Arithmetic Operations(枚举)
题目链接:点击跳转
题意: 给出一个长度为n的序列a,问最少修改几个数字,能使得序列变成等差序列
思路:
- 枚举公差(我取了-300~300),用数组记录每个数字减去位置乘公差的值出现的次数,出现最多的次数就是在枚举范围内的最优解。
- 但是这个枚举不能太大(完整枚举2e5 * 1e5会超时),但是只枚举小范围不能保证正确,如样例3最优解的公差为-20000,那么我们可以遍历数据,取数据中的数的差值作为公差(注意公差要为整数),同样记录,并更新最优解(注意:因为记录的差为2个数的差,但后续遍历没有加上前面这个数,所以更新最优解时,要加上1)。
- 遍历数组不需要跑完整的数组,因为题目规定数据范围为1~1e5,因为前面枚举过了一个范围的值,那么现在要考虑的是没有被枚举过的公差,(这里以300为例), 超过300的公差,在数组里,最完整的情况是334个数构成的序列,300 * 334 = 100200,数组中是不会出现这个数的,所以没有必要遍历整个数组,因为在公差较大的时候,最长的等差数列长度为(极大值/公差),只需要遍历这个长度的序列即可。
- 时间复杂度O(2n*S + 2n * (N/S)), S为枚举范围,N为最大数据范围,这里S = 300, N =100000;(实测S为20也能AC)
代码如下:
1 |
|
CF 1654E Arithmetic Operations(枚举)
http://example.com/2022/03/21/CF 1654E Arithmetic Operations(枚举)/