V1
题目大意
$n$ 个不同的正整数,找出由这些数组成的最长的等差数列。
$n \le 10000,\ a_i \le 10^9$
【$O(n^3)$】
设 $f_{i,j}$ 表示:以第 $i$ 项和第 $j$ 项($i>j$)作为数列最后两项,的最长长度。
转移就是找一个 $k$,使得 $a_i-a_j=a_j-a_k$,然后就 $f_{i,j}=f_{j,k}+1$。
三个变量的枚举,所以是 $O(n^3)$。
【$O(n^2 \log n)$】
我们观察,枚举了 $i$ 和 $j$ 之后,$a_k$ 的值是确定的。
那么搞个东西存下对于每个 $j$ 同一类的 $k$ 的最大 $f$ 值就好了。
如果一开始离散化这个数组,那可以二分求这个 $k$,所以带个 $\log$。
【$O(n^2)$】
实际上不需要离散化也不需要二分,因为如果 $j$ 从大到小枚举,那么 $k$ 是单调递减的。
于是就 $O(n^2)$ 了。
V2
题目大意
$n$ 个不同的正整数,问是否存在由这些数组成的等差数列长度 $\ge 200$。若没有,输出无解,若有,输出最长长度
$n \le 50000,\ a_i \le 10^9$
【随机大法】
我同桌说,看到 $\ge 200$ 这种东西,应当要考虑近似算法。
随机两个下标作为数列的中间两项,然后往两边扩展。做一次的时间是 $O(n)$。
然后不能随机太多,也不要随机重复,所以把数组打乱顺序,取前面大概1000组就可以了。
如果要求的长度过小(比如 3),那这个算法是很难找出来的,但 200 的话还是可以的。