Live2d Test Env

51Nod - 1055:最长等差数列 (求最长的等差数列)

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<= Aii <= 10^9)Output最长等差数列的长度。Sample Input

10
1
3
5
6
8
9
10
12
13
14

Sample Output

5

题意:求一个集合,这个集合的元素排序后是等差数列。

思路:区间dp,用dp[i][j]表示等差数列的第一位和第二位的下标。如果满足a[j]+a[j]==a[i]+a[k],就用dp[j][k]+1去更新qdp[i][j]。

(空间:用short int。。。。

#include<bits/stdc++.h>
using namespace std;
const int maxn=10010;
int a[maxn];
short int dp[maxn][maxn],ans=0;;
map<int,int>mp;
void Max(short int &a,short int b){ if(b>a) a=b; }
int main()
{
    int N,i,j,k;
    scanf("%d",&N);
    for(i=1;i<=N;i++) scanf("%d",&a[i]);
    sort(a+1,a+N+1);
    for(i=1;i<=N;i++) dp[i][i]=1;
    for(i=1;i<=N;i++)
     for(j=i+1;j<=N;j++) dp[i][j]=2;
    if(N>1) ans=2; else ans=1;
    for(j=N-1;j>=1;j--){
        i=j-1; k=j+1;
        while(i>=1&&k<=N){
           if(2*a[j]==a[i]+a[k]) { Max(dp[i][j],dp[j][k]+1); Max(ans,dp[i][j]); i--; k++; }
           else if(2*a[j]>a[i]+a[k]) k++;
           else i--;
        }
    }
    printf("%d\n",ans);
    return 0;  
}   

 

posted @ 2018-06-04 16:00  nimphy  阅读(1140)  评论(0编辑  收藏  举报