Strip CodeForces - 487B (单调队列)

题面: 

Alexandra has a paper strip with n numbers on it. Let's call them ai from left to right.

Now Alexandra wants to split it into some pieces (possibly 1). For each piece of strip, it must satisfy:

  • Each piece should contain at least l numbers.
  • The difference between the maximal and the minimal number on the piece should be at most s.

Please help Alexandra to find the minimal number of pieces meeting the condition above.

 

 

一个显然的思路是ST表求一下最值, 由于最值单调性可以双指针处理出以每个数为右端点时, 左端点的最小值, 然后再dp就行了, 但这样复杂度是$O(nlogn)$的. 若用单调队列处理的话可以达到$O(n)$的, 单调队列还是不太会写啊, 写了1个多小时才A

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;

const int N = 1e6+10, INF = 0x3f3f3f3f;
int n, s, l;
int a[N], dp[N], L[N];

int main() {
	scanf("%d%d%d", &n, &s, &l);
	REP(i,1,n) scanf("%d", a+i);
	deque<int> q;
	int pos = 1;
	REP(i,1,n) {
		while (q.size()&&a[i]-a[q.front()]>s) pos=q.front()+1,q.pop_front();
		L[i] = pos;
		while (q.size()&&a[i]<a[q.back()]) q.pop_back();
		q.push_back(i);
	}
	pos = 1, q.clear();
	REP(i,1,n) {
		while (q.size()&&a[q.front()]-a[i]>s) pos=q.front()+1,q.pop_front();
		L[i] = max(L[i], pos);
		while (q.size()&&a[i]>a[q.back()]) q.pop_back();
		q.push_back(i);
	}
	REP(i,1,n) dp[i]=INF;
	q.clear();
	q.push_back(0);
	REP(i,1,n) {
		while (q.size()&&q.front()<L[i]-1) q.pop_front();
		if (q.size()&&q.front()<=i-l) dp[i]=dp[q.front()]+1;
		while (q.size()&&dp[i]<dp[q.back()]) q.pop_back();
		q.push_back(i);
	}
	printf("%d\n", dp[n]>=INF?-1:dp[n]);
}

 

转载于:https://www.cnblogs.com/uid001/p/10439242.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值