• HDU 3530 Subsequence(单调队列)


    Subsequence

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 3266    Accepted Submission(s): 1063


    Problem Description
    There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minimum element of the subsequence is no smaller than m and no larger than k.
     
    Input
    There are multiple test cases.
    For each test case, the first line has three integers, n, m and k. n is the length of the sequence and is in the range [1, 100000]. m and k are in the range [0, 1000000]. The second line has n integers, which are all in the range [0, 1000000].
    Proceed to the end of file.
     
    Output
    For each test case, print the length of the subsequence on a single line.
     
    Sample Input
    5 0 0 1 1 1 1 1 5 0 3 1 2 3 4 5
     
    Sample Output
    5 4
     
    Source
     
    Recommend
    zhengfeng
     

    很简单的单调队列的题目;

    今天做的时候,一直以为可以二分答案做。

    结果坑了一天,晚上适牛告诉我二分是不对的。

    比如n=5  m=k=3

    1 2 3 4 10000

    二分的时候长度为2挂掉。结果就错了。正确答案应该是4

    只有通过单调队列扫一遍。

    维护一个最大值和一个最小值。

    保证最大值-最小值时满足上界条件的。

    然后如果下界条件满足就更新答案。

    //============================================================================
    // Name        : HDU.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    const int MAXN=100010;
    int a[MAXN];
    int q1[MAXN],q2[MAXN];//q1是维护最大值,q2维护最小值
    int n,m,k;
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        while(scanf("%d%d%d",&n,&m,&k)==3)
        {
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            int ans=0;
            int rear1,front1,rear2,front2;
            rear1=front1=0;
            rear2=front2=0;
            int now=0;
            for(int i=1;i<=n;i++)
            {
                while(front1<rear1 && a[q1[rear1-1]]<a[i])rear1--;
                q1[rear1++]=i;
                while(front2<rear2 && a[q2[rear2-1]]>a[i])rear2--;
                q2[rear2++]=i;
                while(front1<rear1 && front2<rear2 && a[q1[front1]]-a[q2[front2]]>k)
                {
                    if(q1[front1]<q2[front2])
                    {
                        now=q1[front1];
                        front1++;
                    }
                    else
                    {
                        now=q2[front2];
                        front2++;
                    }
                }
                if(front1<rear1 && front2<rear2 && a[q1[front1]]-a[q2[front2]]>=m)
                    ans=max(ans,i-now);
            }
            printf("%d\n",ans);
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    八数码(BFS)
    食物链(并查集)
    最大异或对(Trie)
    解决espeak编译的一些问题
    AcWing 3779. 相等的和
    AcWing 3775. 数组补全(环图)
    AcWing 3728. 城市通电(最小生成树)
    AcWing 3727. 乘方相乘(进位制)
    tarjan
    LC刷题简要记录
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3066034.html
Copyright © 2020-2023  润新知