51nod-1055-最长等差数列(dp+优化)

基准时间限制: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 }

 


posted @ 2018-04-27 10:47  *zzq  阅读(353)  评论(0编辑  收藏  举报