用队列转移dp即可。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mp(x, y) make_pair(x, y)
const int maxn = 100005;
int P[maxn];
int a[maxn];
int dp[maxn];
int st1[maxn][20];
int st2[maxn][20];
pair<int, int> q[maxn];
int n, s;
void init_st()
{
P[0] = -1;
for(int i = 1; i <= n; i++) P[i] = i & (i-1) ? P[i-1] : P[i-1] + 1;
for(int i = 1; i <= n; i++) st1[i][0] = st2[i][0] = a[i];
for(int j = 1; j <= P[n]; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++) {
st1[i][j] = max(st1[i][j-1], st1[i+(1<<(j-1))][j-1]);
st2[i][j] = min(st2[i][j-1], st2[i+(1<<(j-1))][j-1]);
}
}
int query(int l, int r)
{
int k = P[r-l+1];
return max(st1[l][k], st1[r-(1<<k)+1][k]) - min(st2[l][k], st2[r-(1<<k)+1][k]);
}
int solve(int L, int R, int x)
{
int mid, res;
while(L <= R) {
mid = (L + R) >> 1;
if(dp[mid] == -1 || query(mid+1, x) > s) L = mid+1;
else R = mid-1, res = mid;
}
return res;
}
void work()
{
int l;
scanf("%d%d%d", &n, &s, &l);
memset(dp, -1, sizeof dp);
dp[0] = 0;
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
init_st();
int L = 0, R = 0;
q[R++] = mp(0, dp[0]);
for(int i = l; i <= n; i++) {
while(L < R && query(q[L].first+1, i) > s && q[L].first <= i-l) L++;
if(L < R && q[L].first <= i-l) dp[i] = dp[q[L].first] + 1;
else dp[i] = -1;
if(dp[i] != -1) q[R++] = mp(i, dp[i]);
}
printf("%d\n", dp[n]);
}
int main()
{
//freopen("data", "r", stdin);
work();
return 0;
}