思路:
dp
先排个序,放进一个袋子里的显然是一段区间
定义状态:pos[i]表示小于等于i的可以作为(放进一个袋子里的)一段区间起点的离i最近的位置
显然,初始状态:pos[i] = 1,1 <= i <= k
状态转移:
pos[i+1] = i+1 ,如果 a[i] - a[pos[i-k+1]] <= d , 因为在这种情况下pos[i-k+1] 到 i 可以放进一个袋子里,那么i+1就可以作为新的起点了
pos[i+1] = pos[i], 其他情况
最后只要判断pos[n+1] 等不等于 n+1 就可以判断是不是都能放进袋子里
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 5; int a[N], pos[N]; int main() { int n, k, d; scanf("%d%d%d", &n, &k, &d); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a+1, a+1+n); for (int i = 1; i <= k; i++) pos[i] = 1; for (int i = k; i <= n; i++) { int pre = pos[i-k+1]; if(a[i] - a[pre] <= d) pos[i+1] = i+1; else pos[i+1] = pos[i]; //cout << i+1 << " " << pos[i+1] << endl; } if(pos[n+1] == n+1) printf("YES\n"); else printf("NO\n"); return 0; }