1.试题
问题描述
小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。
小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。
现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, … AN。
小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于K)?
输入格式
第一行包含两个个整数N和K。
第二行包含N个整数A1, A2, … AN。
对于30%的数据,1 ≤ N ≤ 10
对于100%的数据,1 ≤ N ≤ 100000, 0 ≤ Ai ≤ 100000, 0 ≤ K ≤ 100000
输出格式
一个整数,代表答案。
样例输入
10 0
1 4 2 8 5 7 1 4 2 8
样例输出
6
2.算法分析
分析积分序列,可以将用户的积分分组:
- 0,k,2k,3k,…
- 1,k+1,2k+1,…
- …
- k-1,2k-1,3k-1,…
可以看出,不同分组用户之间是不可能匹配成功的,因为他们之间的积分差不可能为k,所以我们需要分别在每一组中求出所能选择的最大人数。
设某一组中的积分序列为$\{score[1],score[2],…,score[t]\}$,显然相邻的两个元素(积分)$score[i-1]$和$score[i]$不能同时选,但是积分$score[i-2]$却能和$score[i]$同时选择。因此,当计算到第$i$个元素时,该元素是否选择只和第$i-1$和第$i-2$的状态有关。
考虑动态规划。
设$f[i]$为在某一分组下,当选到第$i$个元素是能够同时选择的最大人数,$cnt[i]$为积分等于$i$的人数,则有
将K个分组的$f[t]$加起来,就是最后的答案$ans$。
时间复杂度:$O(MaxSore)$,即输入的最大积分。
3.代码
1 | //group + DP |