zoukankan      html  css  js  c++  java
  • hdu 3530 Subsequence 最长的连续子序列,使得 M<=Max-Min<=K

    Subsequence

    http://acm.hdu.edu.cn/showproblem.php?pid=3530

     【 题意】:给出一个序列,求最长的连续子序列,使得 M<=Max-Min<=K
                    n <= 10^5

     【思路】:单调队列可以快速知道i及之前的最大/小值。

               这里可以 枚举每个i为序列尾 ,并维护两个单调队列,一个存单调递减,一个存单调递增 

               如果2个队列的队头的差别大于m2,那么就通过减小大的(递减序列的fron2++),增大小的(递增序列的        front1++)来是dif更小,到底是front1++的还是front2++,应该哪个距离i最远(下标号较小)就哪个++,因为到时候我们要取的是距离i较小(下表好较大)的

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 int a[100010];
     7 int q[100010],qq[100010];//Max, Min
     8 
     9 int main()
    10 {
    11     int N,M,K;
    12     while(~scanf("%d%d%d",&N,&M,&K))
    13     {
    14         for(int i=1;i<=N;i++)
    15             scanf("%d",&a[i]);
    16         int ans = 0;
    17         int front1 = 0,tail1 = 0;
    18         int front2 = 0,tail2 = 0;
    19         int last1 = 0,last2 = 0;
    20         for(int i=1;i<=N;i++)
    21         {
    22             //Max
    23             while(front1<tail1 && a[qq[tail1-1]]<=a[i])tail1--;//  da
    24             while(front2<tail2 && a[qq[tail2-1]]>=a[i])tail2--;//xiao
    25             qq[tail2++] = q[tail1++] = i;
    26             while(a[q[front1]]-a[qq[front2]] > K)
    27             {
    28                 if(q[front1]<qq[front2])
    29                     last1 = q[front1++];   
    30     /*需要先记录上一次的被淘汰的最值位置last ,这样[last+1,i]即为满足条件的连续子序列了
    31       所以 前面 a[qq[tail1-1]]<=a[i] 而不是a[qq[tail1-1]]<a[i]  不然的话 last+1 的值可
    32       能和last的只是一样的 同样不满足
    33      长度为 i-(last+1)+1  即 i-ans   */
    34                 else
    35                     last2 = qq[front2++];
    36                 /*   qq[]是单调递减的  front2++是减小最大值   q[]是单调递增的 front1++ 是增大最小值
    37                 都可以使他们的dif减小  到底要减小哪个   应该哪个距离i最远就减小哪个*/
    38             }
    39             if(a[q[front1]]-a[qq[front2]]>=M)
    40                 ans = max(ans,i-max(last1,last2));//取较大值
    41         }
    42         printf("%d
    ",ans);
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    C#读取系统信息
    C# 读取驱动器盘符及信息
    for循环里的break,continue和return有什么差别
    monkey
    ZXing
    python中os模块的常用接口和异常中Exception的运用
    python中的字典应用实例
    python中的列表和字典
    python中如何单独测试一个函数的作用
    数据挖掘概念与技术PDF
  • 原文地址:https://www.cnblogs.com/assult/p/3478091.html
Copyright © 2011-2022 走看看