题意:
思路:
首先肯定需要排个序,然后分段DP
但是平常写的分段DP都是n^2的,这里的可以发现单调性,因此考虑双指针转移
这里两个指针都代表两个段的右端点
这里双指针的合理性很明显
想象指针为了满足位置相距K,先j=max(j,i+K)了
然后还得满足极差<=D,因此需要移动几个距离
合理性重点在于当另一个指针i往前移动一格时,j有没有必要回溯
答案是没有必要,因为回溯会导致极差更小,而相距距离也更小了
Code:
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int mxn=5e5+10;
int N,K,D;
int a[mxn],dp[mxn];
void solve(){
cin>>N>>K>>D;
for(int i=1;i<=N;i++) cin>>a[i];
sort(a+1,a+1+N);
int j=1;
dp[0]=1;
for(int i=0;i<=N;i++){
if(dp[i]){
j=max(j,i+K);
while(j<=N&&a[j]-a[i+1]<=D) dp[j]=1,j++;
}
}
if(dp[N]==1) cout<<"YES"<<'\n';
else cout<<"NO"<<'\n';
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int __=1;//cin>>__;
while(__--)solve();return 0;
}