【51nod 1055 & 1056】最长等差数列及V2 题解

V1

题目大意

  nn 个不同的正整数,找出由这些数组成的最长的等差数列。
  n10000, ai109n \le 10000,\ a_i \le 10^9

O(n3)O(n^3)

  设 fi,jf_{i,j} 表示:以第 ii 项和第 jj 项(i>ji>j)作为数列最后两项,的最长长度。

  转移就是找一个 kk,使得 aiaj=ajaka_i-a_j=a_j-a_k,然后就 fi,j=fj,k+1f_{i,j}=f_{j,k}+1

  三个变量的枚举,所以是 O(n3)O(n^3)

O(n2logn)O(n^2 \log n)

  我们观察,枚举了 iijj 之后,aka_k 的值是确定的。
  那么搞个东西存下对于每个 jj 同一类的 kk 的最大 ff 值就好了。
  如果一开始离散化这个数组,那可以二分求这个 kk,所以带个 log\log

O(n2)O(n^2)

  实际上不需要离散化也不需要二分,因为如果 jj 从大到小枚举,那么 kk 是单调递减的。
  于是就 O(n2)O(n^2) 了。

V2

题目大意

  nn 个不同的正整数,问是否存在由这些数组成的等差数列长度 200\ge 200。若没有,输出无解,若有,输出最长长度
  n50000, ai109n \le 50000,\ a_i \le 10^9

【随机大法】

  我同桌说,看到 200\ge 200 这种东西,应当要考虑近似算法。

  随机两个下标作为数列的中间两项,然后往两边扩展。做一次的时间是 O(n)O(n)
  然后不能随机太多,也不要随机重复,所以把数组打乱顺序,取前面大概1000组就可以了。

  如果要求的长度过小(比如 3),那这个算法是很难找出来的,但 200 的话还是可以的。