码迷,mamicode.com
首页 > 其他好文 > 详细

Strip CodeForces - 487B (单调队列)

时间:2019-02-26 19:12:03      阅读:267      评论:0      收藏:0      [点我收藏+]

标签: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:

  • 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]);
}

 

Strip CodeForces - 487B (单调队列)

标签:names   lower   ini   queue   div   must   efi   cpp   mini   

原文地址:https://www.cnblogs.com/uid001/p/10439242.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!