HDU 3530 单调队列

Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 3995    Accepted Submission(s): 1308

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

题意:求一个最长子序列,使得最大值与最小值差值在mi,mx范围内,

用一个递增,一个递减两个单调队列维护最大值,最小值,然后扫描一遍,队列的起点从最近一个被单调队列抛弃的下标+1算起。

代码:

/* ***********************************************
Author :_rabbit
Created Time :2014/5/13 10:30:48
File Name :C.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
int a[100100],que1[100100],que2[100100];
int main()
{
     //freopen("data.in","r",stdin);
     //freopen("data.out","w",stdout);
     int n,mx,mi;
     while(~scanf("%d%d%d",&n,&mi,&mx)){
         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
         int head1=0,tail1=0,head2=0,tail2=0;
		 int last1=0,last2=0;
         int ans=0;
         for(int i=1;i<=n;i++){
             while(head1<tail1&&a[que1[tail1-1]]>a[i])tail1--;//递增
             que1[tail1++]=i;
             while(head2<tail2&&a[que2[tail2-1]]<a[i])tail2--;//递减
             que2[tail2++]=i;
             while(a[que2[head2]]-a[que1[head1]]>mx){
                 if(que1[head1]<que2[head2])head1++;
                 else head2++;
             }
             if(a[que2[head2]]-a[que1[head1]]>=mi)
                 ans=max(ans,i-max(que1[head1-1],que2[head2-1]));
         }
         cout<<ans<<endl;
     }
     return 0;
}

HDU 3530 单调队列

时间: 2024-10-13 08:29:16

HDU 3530 单调队列的相关文章

hdu 3530 单调队列水题

给你一个数列找到最长的子序列   中的最大值减最小值值m   k之间 建立两个单调队列   一个递增    一个递减    当两个队首满足情况是就进行比较 找到最大值 当不满足是旧的移动队首      怎样移??? 移动队首id较小的一个 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; int max(int a,int b) { return a>b?a:b

HDU 3507 单调队列 斜率优化

斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方法来做,但是该题要求的是区间和的平方,于是要转换单调的计算方法为斜率,也就是凸线. 其他就是最基本的单调DP /** @Date : 2017-09-04 15:39:05 * @FileName: HDU 3507 单调队列 斜率优化 DP.cpp * @Platform: Windows * @

hdu 3415 单调队列

Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5690    Accepted Submission(s): 2059 Problem Description Given a circle sequence A[1],A[2],A[3]......A[n]. Circle s

hdu 3401 单调队列优化+dp

http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5188    Accepted Submission(s): 1776 Problem Description Recently, lxhgww is addicted to stoc

hdu 3401(单调队列优化dp)

注意:这题题意是有操作的天数相隔要大于w 然后列出状态转移方程就可以发现,可以用优点队列优化啦. 构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱 状态转移有: 1.从前一天不买不卖: dp[i][j]=max(dp[i-1][j],dp[i][j]) 2.从前i-W-1天买进一些股: dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j]) 3.从i-W-1天卖掉一些股: dp[i][j]=max(dp[i-W-1][k]+(k-j)*

hdu 4193 单调队列

题意是给你n个数   组成的环   求以一个数开头 的数列所有前缀都为非负数的数列的个数: 思路:  先扩展成2*n的数列 然后求出sum[i]表示前i项的和     对每个i>.=n结尾的数列  只要单调队列里的最小值大于等于sum[i-n]就满足情况(想想为什么)   对于单调队列  只要维护长度大于等于n   递增的就行: #include<stdio.h> #include<string.h> #include<iostream> using namesp

hdu 4374 单调队列

求最大不超过k的连续子序列的和   单调队列 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; int num[201000],id[201000],sum[201000]; int main() { int n,m,i,j,T; scanf("%d",&T); while(T--) { scanf("%d%d",&am

HDU 4122 单调队列

转载自:http://blog.csdn.net/lvshubao1314/article/details/46910271 DES :给出n个订单和m是商店的开放时间.然后n行给出n个订单的信息.然后给出t和s.表示一个月饼的保质期和保存一天的成本.最后m行,给出每个时刻做月饼的成本.问.完成订单的最少的成本是多少. 思路就是用单调队列保存每个点之前的可以为这个点做月饼的点.刚学了单调队列.在保存下标然后找到值哪里还是有一些混乱. 第一次错了.闰年是366天.搞混了.T_T.不过时间方面的计算

hdu 5289 单调队列

#include <iostream> #include <cstdio> #include <queue> #include <deque> using namespace std; typedef pair<int, int> P; #define maxn 100000 + 10 deque<long long> Q1; //up deque<long long> Q2; //down int n, k; long