hdu 3530 动态规划 单调DP

题意:求最长的子序列 使 m <= 最大值-最小值 <= k

分析:两个单调队列,一增一减,当 max-min>k 时,队首元素出队,当 max-min<m 时,不必出队,

因为后来加入的元素可能使差值变大,但不可能使差值变小

 

 

const int maxn=100005;
int mi,ma;
struct que{
    int ans,pre;
    int a[maxn], pa[maxn], la, ra;
    int b[maxn], pb[maxn], lb, rb;
    void init(){ la=lb=1; ra=rb=0; pre=0; ans=0;}
    void ins(int p,int v){
        while( la<=ra && v>=a[ra] ) ra--;//最大
        ra++; pa[ra]=p; a[ra]=v;

        while( lb<=rb && v<=b[rb] ) rb--;//最小
        rb++; pb[rb]=p; b[rb]=v;

        while( a[la]-b[lb] > ma ){
            if(pa[la]<pb[lb]) pre=pa[la],la++;
            else pre=pb[lb],lb++;
        }

        if(a[la]-b[lb] >= mi && ans<p-pre) ans=p-pre;
    }
}q;

int main(){
    int n,p,v;
    while(scanf("%d%d%d",&n,&mi,&ma)!=EOF){
        q.init();
        for(p=1;p<=n;p++){
            scanf("%d",&v);
            q.ins(p,v);
        }
        printf("%d\n",q.ans);
    }
    return 0;
}

 

posted @ 2013-06-19 14:00  心向往之  阅读(165)  评论(0编辑  收藏  举报