基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题
收藏
关注
N个不同的正整数,找出由这些数组成的最长的等差数列。
例如:1 3 5 6 8 9 10 12 13 14
等差子数列包括(仅包括两项的不列举)
1 3 5
1 5 9 13
3 6 9 12
3 8 13
5 9 13
6 8 10 12 14
其中6 8 10 12 14最长,长度为5。
Input
第1行:N,N为正整数的数量(3 <= N <= 10000)。 第2 - N+1行:N个正整数。(2<= A[i] <= 10^9)
Output
最长等差数列的长度。
Input示例
10 1 3 5 6 8 9 10 12 13 14
Output示例
5
一开始想的是dp+哈希,复杂度是O(N*N*log(N)),结果T了,后来看题解发现还有这种优化操作。对于等差数列 a[k],a[i],a[j],必然满足a[i]*2==a[k]+a[j],我们可以枚举所有的i,
然后用两个指针前后移动找到符合要求的状态再进行转移,复杂度O(N^2);
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cstdio> 5 #include<stack> 6 #include<set> 7 #include<map> 8 #include<cmath> 9 #include<ctime> 10 #include<time.h> 11 #include<algorithm> 12 using namespace std; 13 #define mp make_pair 14 #define debug puts("debug") 15 #define LL long long 16 #define pii pair<int,int> 17 map<int,int>M; 18 short f[10010][10010]; 19 int a[10010],N; 20 int main(){ 21 int n,i,j,k; 22 cin>>n; 23 N=n; 24 for(i=1;i<=n;++i) { 25 scanf("%d",a+i); 26 } 27 sort(a+1,a+1+n); 28 short ans=0; 29 for(i=1;i<=n;++i){ 30 int j=i+1,k=i-1; 31 while(k>=1&&j<=n){ 32 if(a[k]+a[j]<a[i]*2) j++; 33 else if(a[k]+a[j]>a[i]*2) k--; 34 else{ 35 f[i][j]=max(f[i][j],short(max(f[k][i],(short)2) 36 +1)); 37 ans=max(ans,f[i][j]); 38 k--; 39 j++; 40 } 41 } 42 } 43 cout<<ans<<endl; 44 return 0; 45 }