• 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
    ",ans);
    70     }
    71     return 0;
    72 }
    View Code
    keep moving...
  • 相关阅读:
    第三次冲刺--软件工程
    【操作系统】实验四 主存空间的分配和回收
    《构造之法》8、9、10
    实验三 进程调度模拟程序--操作系统
    构建之法读后感
    操作系统作业调度-操作系统
    结对评论—软件工程
    复利计算6.0—软件工程(web版本)
    学习进度条
    第三次冲刺总结
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3184191.html
Copyright © 2020-2023  润新知