hdu 3530

   题目意思是找出一个给出的序列的子序列,使得其中的最大与最小值的差满足一定的范围。此种线性dp一般只有O(n)的算法才可以过,因此单调队列是最好的选择。发觉对单调队列的理解还不够啊。。。写的时候还是写成了一个自创的XX队列,只是水过了sample,看来还要继续努力~~

     解法就是用两个单调队列,一个维护最小值,一个维护最大值。队列里装的是下标。但队列的“平衡”(队首元素之差不在目标范围内)被打破时,就要在两条队列中的队首中将所保存的标号较小的元素出队,直到恢复平衡。然后再计算此时的子串长度。

 

     以下是参考yuan神的代码后写出来的:

 

  1. #include "stdio.h"

  2. const int N=100100;
    int a[N];
    int queue1[N],queue2[N];
    int n,m,k;
  3. int max(int a,int b) {return a>b?a:b;}
  4. int main()
    {
  5.  while(scanf("%d%d%d",&n,&m,&k)==3)
     {
      int i,j;
      int front1=0,rear1=0,front2=0,rear2=0;
      int last1=0,last2=0;
      int ans=0;

  6.   for(i=1;i<=n;i++)
       scanf("%d",&a[i]);

  7.   for(i=1;i<=n;i++)
      {
       while(front1<rear1 && a[queue1[rear1-1]]<=a[i]) rear1--;
       queue1[rear1++]=i;
       while(front2<rear2 && a[queue2[rear2-1]]>=a[i]) rear2--;
       queue2[rear2++]=i;
       while(a[queue1[front1]]-a[queue2[front2]]>k)
       {
        if(queue1[front1]<queue2[front2]) last1=queue1[front1++];
        else last2=queue2[front2++];
       }
       if(a[queue1[front1]]-a[queue2[front2]]>=m)
        ans=max(ans,i-max(last1,last2));
      }

  8.   printf("%d/n",ans);
     }
     return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值