Asia Yokohama Regional Contest 2018 B题 - Arithmetic Progressions(dp)

https://codeforces.com/gym/102082

题意

给定一些数,可以重新排序,求其中最长的等差数列的长度

思路

d[i][j]表示以a[i]和a[j]为开头的等差数列的最大长度,具体见代码

if后面意思就是说两边加起来等于中间的值两倍的时候就可以构成等差数列了,比中间值两倍大的话就要去移动左指针使其变小,比中间值两倍要小的话就要去移动右指针使其变大,反正目的就是要找到可以构成等差数列的点。

 1 #define bug(x,y) cout<<"i="< 2 #define IO std::ios::sync_with_stdio(0);
 3 #include 
 4 #define itor ::iterator
 5 using namespace  std;
 6 typedef long long ll;
 7 typedef pairP;
 8 #define pb push_back
 9 #define se second
10 #define fi first
11 #define rs o*2+1
12 #define ls o*2
13 const int N=5e3+5;
14 int n;
15 int a[N],d[N][N];
16 int main(){
17     scanf("%d",&n);
18     for(int i=1;i<=n;i++){
19         scanf("%d",&a[i]);
20     }
21     sort(a+1,a+1+n);
22     for(int i=1;i<=n;i++){
23         for(int j=1;j<=n;j++)d[i][j]=2;
24     }
25     int ans=2;
26     for(int i=n-1;i>=2;i--){
27         int j=i-1,k=i+1;
28         while(j>=1&&k<=n){
29             if(a[j]+a[k]==2*a[i]){
30                 d[j][i]=d[i][k]+1;
31                 ans=max(ans,d[j][i]);
32                 j--;k++;
33             }
34             else if(a[j]+a[k]<2*a[i]){
35                 k++;
36             }
37             else if(a[j]+a[k]>2*a[i]){
38                 j--;
39             }
40         }
41     }
42     printf("%d\n",ans);
43 }

 

转载于:https://www.cnblogs.com/ccsu-kid/p/10599443.html

你可能感兴趣的:(Asia Yokohama Regional Contest 2018 B题 - Arithmetic Progressions(dp))