51nod1055 最长等差数列
【题解】
DP题,用f[i][j]表示以i为最后一个数、以j为倒数第二个数的等差数列的长度。转移显然,不过在寻找满足a[i]-a[j]=a[j]-a[k]的k的时候,要注意随着i的递增,k其实是递减的,所以总的复杂度可以降到n^2.
1 #include<cstdio> 2 #include<algorithm> 3 #define N 10010 4 #define rg register 5 using namespace std; 6 short n,f[N][N],ans; 7 int a[N]; 8 inline int read(){ 9 int k=0,f=1; char c=getchar(); 10 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 11 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 12 return k*f; 13 } 14 inline short max(short x,short y){return x>y?x:y;} 15 int main(){ 16 n=read(); 17 for(rg int i=1;i<=n;i++) a[i]=read(); 18 sort(a+1,a+1+n); 19 for(rg int i=0;i<=n;i++) 20 for(rg int j=0;j<=n;j++) f[i][j]=2; 21 for(rg int i=1;i<=n-1;i++){ 22 int pre=i-1; 23 for(rg int j=i+1;j<=n;j++){ 24 while(pre&&a[j]-a[i]>a[i]-a[pre]) pre--; 25 if(!pre) break; 26 if(pre&&a[j]-a[i]==a[i]-a[pre]) f[j][i]=max(f[j][i],f[i][pre]+1); 27 ans=max(ans,f[j][i]); 28 } 29 } 30 printf("%d\n",ans); 31 return 0; 32 }