HDU 3530 Subsequences(单调队列)

解题思路:

开两个单调队列即可。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define LL long long
using namespace std;
const int maxn = 100000 + 10;
int A[maxn];
int Q1[maxn];
int Q2[maxn];
int P1[maxn];
int P2[maxn];
int Min[maxn];
int Max[maxn];
int N, M, K;
int main()
{
	while(scanf("%d%d%d", &N, &M, &K)!=EOF)
	{
		for(int i=1;i<=N;i++)
			scanf("%d", &A[i]);
		int head1 = 1, tail1 = 0;
		int head2 = 1, tail2 = 0;
		int now = 0, ans = 0;
		for(int i=1;i<=N;i++)
		{
			while(head1 <= tail1 && A[P1[tail1]] <= A[i])
				tail1--;
			P1[++tail1] = i;
			while(head2 <= tail2 && A[P2[tail2]] >= A[i])
				tail2--;
			P2[++tail2] = i;
			while(A[P1[head1]] - A[P2[head2]] > K)
			{
				if(P1[head1] < P2[head2])
					now = P1[head1++];
				else
					now = P2[head2++];
			}
			if(A[P1[head1]] - A[P2[head2]] >= M)
				ans = max(ans, i - now);

		}
		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-08-15 15:41:46

HDU 3530 Subsequences(单调队列)的相关文章

hdu 3530 (单调队列)

Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4441    Accepted Submission(s): 1457 Problem Description There is a sequence of integers. Your task is to find the longest subsequenc

HDU 3401 Trade(单调队列优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:炒股.第i天买入一股的价钱api,卖出一股的价钱bpi,最多买入asi股,最多卖出bsi股.两次操作(买入或卖出)中间必须相差W天.炒股时间为n.任意时间手中的股票不大于MaxP.求最大收益. dp[i][j]代表第i天手上有j股的最大收益,dp[i][j]=max(dp[i-1][j],dp[i-W][k]+(j-k)*ap[i],dp[i-W][k]+(k-j)*bp[i]); dp

HDU 5289 Assignment(单调队列)

Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 297    Accepted Submission(s): 152 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro

hdu 2430 Beans 单调队列

#include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> using namespace std; //题意:从num[1]~num[n]中取一段连续的序列,使得(num[i]+...+num

hdu 4374 (单调队列+dp)

d[i][j]表示i行j列格子可以得到的最大值 顺着来的时候 d[i][j]=max(d[i-1][k]+sum[k...j])=max(d[i-1][k]-sum[1..k-1]+sum[1...j])  sum[1...j]是固定值 只要找d[i-1][k]+sum[1...k]  的最大值就可以了 找法就是维护一个单调递减的队列,每次加入一个值进去就把队列值后面小于它的点都删掉,把前面j-k>t的点删掉(走的步数大于t步),d[i][j]=队首值+sum[1...j] 逆着来的时候 d[i

HDU 3507 PrintArticle (单调队列优化)

题意:给出一个数列C,一个数字M,将数列分成若干段,每段的代价为(设这段的数字为k个): dp[i]=min(dp[j]+(sum[i]-sum[j])*(sum[i]-sum[j])+M) 若j1<j2且j2比j1优 dp[j1]+sum[i]^2+sum[j1]^2-2*sum[i]*sum[j1]+M>dp[j2]+sum[i]^2+sum[j2]^2-2*sum[i]*sum[j2] dp[j1]-dp[j2]+sum[j1]^2-sum[j2]^2>2*sum[i]*(sum[

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 subsequenc

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 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch