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