题意:求 n n n个数中最长的等差数列(差任意)
思路:
利用等差数列的性质:
若
a
[
i
]
、
a
[
j
]
、
a
[
k
]
a[i]、a[j]、a[k]
a[i]、a[j]、a[k]为等差数列,则一定有:
a
[
j
]
∗
2
=
a
[
i
]
+
a
[
k
]
a[j]*2 = a[i] + a[k]
a[j]∗2=a[i]+a[k]
故我们考虑枚举这么一个三元组进行DP。
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为
1
−
j
1-j
1−j中满足以
a
[
j
]
a[j]
a[j]结尾,公差为
d
=
a
[
j
]
−
a
[
i
]
d = a[j]-a[i]
d=a[j]−a[i]的最长等差数列的长度
考虑枚举三元组的中间数的位置
i
i
i
设
l
=
i
−
1
l = i-1
l=i−1、$ r = i+1$
当
a
[
l
]
+
a
[
r
]
>
2
∗
a
[
i
]
a[l] + a[r] > 2*a[i]
a[l]+a[r]>2∗a[i]时
l
−
−
l--
l−−
a
[
l
]
+
a
[
r
]
<
2
∗
a
[
i
]
a[l] + a[r] < 2*a[i]
a[l]+a[r]<2∗a[i]时
r
+
+
r++
r++
a
[
l
]
+
a
[
r
]
=
=
2
∗
a
[
i
]
a[l] +a[r] == 2*a[i]
a[l]+a[r]==2∗a[i]时,更新
d
p
[
i
]
[
r
]
=
d
p
[
l
]
[
i
]
+
1
dp[i][r] = dp[l][i] + 1
dp[i][r]=dp[l][i]+1
初始时每一个 d p dp dp数组里的元素值均为 2 2 2。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int A = 1e4 + 10;
short int dp[A][A];
int a[A];
int main(){
int n;
scanf("%d",&n);
for(int i=0 ;i<n ;i++) scanf("%d",&a[i]);
sort(a,a+n);
int ans = 0;
for(int i=0 ;i<n ;i++){
int l = i-1,r = i+1;
while(l>=0 && r<n){
if(a[l]+a[r] > 2*a[i]) l--;
else if(a[l] + a[r] < 2*a[i]) r++;
else{
dp[i][r] = dp[l][i] + 1;
if(dp[i][r] > ans) ans = dp[i][r];
l--;r++;
}
}
}
printf("%d\n",ans+2);
return 0;
}