解题关键:考虑到选择的人积分不能存在差为k,我们可以尝试把以某个数开始,后面相距为k的数提取出来,对他们做出选择,这样子其他的数要么不存在差为k,要么可以重复上面的步骤,而且和上一步没有任何关系。
完整思路:用map把每个积分数的用用户存起来,从当前位置开始找后面连续差为k的所有数然后存下来,对于存下来的数做一个简单dp(选出其子序列,要求子序列在原数组中不相邻,并且取得值最大),然后把结果加到答案中
import javax.print.DocFlavor;
import java.io.*;
import java.util.*;
public class Main {
static Scanner cin=new Scanner(System.in);
public static void main(String args[]) throws IOException{
int t= 1;
while(t--!=0){
solve();
}
}
private static void solve() throws IOException {
int n= cin.nextInt();
int k= cin.nextInt();
int[] a=new int[n];
Map<Integer,Integer> map=new HashMap<>();
for (int i = 0; i < n; i++) {
a[i]= cin.nextInt();
map.put(a[i],map.getOrDefault(a[i],0)+1);
}
boolean[] st=new boolean[100010];
int ans=0;
if(k==0){
System.out.println(map.size());
return;
}
for (int cnt:map.keySet()){
if(st[cnt])continue;
List<Integer> list=new ArrayList<>();
while(map.containsKey(cnt)){
list.add(cnt);
st[cnt]=true;
cnt+=k;
}
int[] dp=new int[list.size()];
int m= list.size();
int max=0;
for (int i = 0; i < m; i++) {
dp[i]=map.get(list.get(i));
for (int j = 0; j < i-1; j++) {
dp[i]=Math.max(dp[i],dp[j]+map.get(list.get(i)));
}
max=Math.max(max,dp[i]);
}
ans+=max;
}
System.out.println(ans);
}
}