题目如下:
代码如下:
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int MAX = 500010;
long long arr[MAX], s[MAX], dp[MAX], f[MAX];
map<int, bool>vis;
int main() {
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> arr[i];
s[arr[i]] ++; //每个数据计数
}
sort(arr, arr + n); //对序列排序
int sum = 0;
if (k == 0) { //单独讨论k==0的情况
for (int i = 1; i < n; i++) {
if (arr[i] != arr[i - 1]) sum++;
}
cout << sum + 1 << endl;
return 0;
}
//dp思路是:dp[x] = max(dp[x - k], dp[x - k * 2] + s[x]);将间隔不超过2k的序列链接起来
for (int i = 0; i < n; i++) {
if (arr[i] >= k * 2)
dp[arr[i]] = max(dp[arr[i] - k], dp[arr[i] - k * 2] + s[arr[i]]);
else if (arr[i] < k) dp[arr[i]] = s[arr[i]];
else dp[arr[i]] = max(dp[arr[i] - k], s[arr[i]]);
//cout << dp[arr[i]] << " ";
}
if (arr[n - 1] == 0) { //序列全为0单独讨论
cout << n << endl;
return 0;
}
for (int i = n - 1; i >= 0; i--) {
if (s[arr[i] + k] || arr[i] == arr[i + 1]) continue;
if (!s[arr[i] + k * 2]) { //如果前面没有链接上类似:n = 6 k = 2 arr为 1 7 9 15 17 21的情况
sum += dp[arr[i]];
}
}
cout << sum << endl;
return 0;
}