题面:
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]); }