HDU4521+线段树+dp

题意:在一个序列中找出最长的某个序列。找出的序列满足题中的条件。

关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小。可以利用线段树进行统计,查询。更新的时候利用dp的思想。

 1 /*

 2 统计某一段内有多少比aim小的数据

 3 在更新的时候利用了dp的思想。

 4 */

 5 #include<stdio.h>

 6 #include<string.h>

 7 #include<stdlib.h>

 8 #include<algorithm>

 9 using namespace std;

10 const int maxn = 100005;

11 struct node{

12     int sum,l,r;

13 }anode[ maxn<<2 ];

14 #define left( x ) (x<<1)

15 #define right( x ) ((x<<1)+1)

16 

17 int data[ maxn ],dp[ maxn ];

18 

19 void build( int l,int r,int n ){

20     anode[ n ].l = l;

21     anode[ n ].r = r;

22     anode[ n ].sum = 0;

23     if( l==r ) return ;

24     int mid = (l+r)/2;

25     build( l,mid,left( n ) );

26     build( mid+1,r,right( n ) );

27     return ;

28 }

29 

30 void update( int aim_pos,int aim_value,int l,int r,int n ){

31     if( l==r ){

32         anode[ n ].sum = aim_value;

33         return ;

34     }

35     int mid = (l+r)/2;

36     if( aim_pos<=mid ) update( aim_pos,aim_value,l,mid,left( n ) );

37     else update( aim_pos,aim_value,mid+1,r,right( n ) );

38     anode[ n ].sum = max( anode[ left( n ) ].sum,anode[ right( n ) ].sum );

39 }

40 

41 int query( int a,int b,int l,int r,int n ){

42     if( a==l&&b==r ){

43         return anode[ n ].sum;

44     }

45     int mid = (l+r)/2;

46     if( b<=mid ) return query( a,b,l,mid,left( n ) );

47     else if( mid<a ) return query( a,b,mid+1,r,right( n ) );

48     else return max( query( a,mid,l,mid,left( n ) ),query( mid+1,b,mid+1,r,right( n ) ) );

49 }

50 

51 int main(){

52     int n ,d;

53     while( scanf("%d%d",&n,&d)==2 ){

54         memset( dp,0,sizeof( dp ));

55         int maxNum = 0;

56         for( int i=1;i<=n;i++ ){

57             scanf("%d",&data[i]);

58             maxNum = max( maxNum,data[ i ] );

59         }

60         build( 0,maxNum,1 );

61         int ans = 1;

62         for( int i=1;i<=n;i++ ){

63             if( i-d>1 )

64                 update( data[ i-1-d ],dp[ i-1-d ],0,maxNum,1 );

65             if( data[ i ]>0 ) dp[ i ] = query( 0,data[ i ]-1,0,maxNum,1 )+1;

66             else dp[ i ] = 1;

67             ans = max( ans,dp[ i ]) ;

68         }

69         printf("%d\n",ans);

70     }

71     return 0;

72 }
View Code

 

你可能感兴趣的:(HDU)