思路:简单dp,用st表+单调队列维护一下。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 1e5 + 7; const int M = 1e7 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1000000007; int n, s, l, tot, head, rear, a[N], dp[N], stk[N], Log[N]; struct ST { int dp[N][20],ty; void build(int n, int b[], int _ty) { ty = _ty; for(int i = 1; i <= n; i++) dp[i][0] = ty * b[i]; for(int j = 1; j <= Log[n]; j++) for(int i = 1; i+(1<<j)-1 <= n; i++) dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]); } int query(int x, int y) { int k = Log[y - x + 1]; return ty * max(dp[x][k], dp[y-(1<<k)+1][k]); } }mx, mn; bool check(int L, int R) { return mx.query(L, R) - mn.query(L, R) <= s; } int main() { for(int i = -(Log[0]=-1); i < N; i++) Log[i] = Log[i - 1] + ((i & (i - 1)) == 0); memset(dp, -1, sizeof(dp)); scanf("%d%d%d", &n, &s, &l); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); mx.build(n, a, 1); mn.build(n, a, -1); head = 1, rear = 0; for(int i = 1; i <= n; i++) { if(i >= l && check(1, i)) { dp[i] = 1; stk[++rear] = i; continue; } while(rear >= head && !check(stk[head] + 1, i)) head++; if(rear >= head && i - stk[head] >= l) { dp[i] = dp[stk[head]] + 1; stk[++rear] = i; } } printf("%d\n", dp[n]); return 0; } /* 76 63 14 89 87 35 20 15 56 */