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.

 

 

单调队列还是不太会写啊, 写了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]);
}

 

上一篇:《云计算:原理与范式》一第3章 云时代的“集成即服务”范式使人受益匪浅


下一篇:centos6.6 NFS服务器搭建