首页 > 代码库 > zoj 2527 - Series
zoj 2527 - Series
题目:计算最长的等差数列长度。
分析:dp,LIS类似物,二分。先排序,然后枚举前面的所有点作为前一个元素求公差即可。
更新时,利用二分找到,距离当前位置最近的前第二元素,
如果不存在,则直接更新为 2即可。
说明:如果数据范围小的话,可在连续区间dp(O(L^2))。(2011-10-03 17:34)
#include <stdio.h> #include <stdlib.h> int D[ 1005 ]; int F[ 1005 ][ 1005 ]; int cmp( const void* a, const void* b ) { return *((int *)a) - *((int *)b); } int find( int h, int key ) { int m,l = 1; while ( l < h ) { m = (l+h)>>1; if ( D[ m ] <= key ) l = m+1; else h = m; } return h; } int main() { int n; while ( ~scanf("%d",&n) ) { for ( int i = 1 ; i <= n ; ++ i ) scanf("%d",&D[ i ]); qsort( &D[ 1 ], n, sizeof( int ), cmp ); for ( int i = 1 ; i <= n ; ++ i ) for ( int j = 1 ; j < i ; ++ j ) F[ i ][ j ] = 1; for ( int i = 2 ; i <= n ; ++ i ) for ( int j = 1 ; j < i ; ++ j ) { int d = D[ i ]-D[ j ]; int s = find( j, D[ j ]-d )-1; if ( s > 0 && D[ s ] == D[ j ]-d ) { if ( F[ i ][ j ] <= F[ j ][ s ] ) F[ i ][ j ] = F[ j ][ s ] + 1; }else if ( s <= 0 || F[ i ][ j ] < 2 ) F[ i ][ j ] = 2; } int Min = 1; for ( int i = 1 ; i <= n ; ++ i ) for ( int j = 1 ; j < i ; ++ j ) if ( Min < F[ i ][ j ] ) Min = F[ i ][ j ]; printf("%d\n",Min); } return 0; }
zoj 2527 - Series
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。