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

 

posted @ 2013-07-11 16:20  xxx0624  阅读(577)  评论(0编辑  收藏  举报