标签:names lower ini queue div must efi cpp mini
题面:
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:
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]);
}
Strip CodeForces - 487B (单调队列)
标签:names lower ini queue div must efi cpp mini
原文地址:https://www.cnblogs.com/uid001/p/10439242.html