题目描述
小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。
小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是 K 的两名用户匹配在一起。如果两人分差小于或大于 K,系统都不会将他们匹配。
现在小明知道这个网站总共有 N 名用户,以及他们的积分分别是 A1,A2,⋯AN。
小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于 K)?
输入描述
输入描述
第一行包含两个个整数 N,K。
第二行包含 N 个整数 A1,A2,⋯AN。
其中,1≤N≤105,0≤Ai≤105,0≤K≤105。
输出描述
输出一个整数,代表答案。
输入输出样例
示例
输入
10 0
1 4 2 8 5 7 1 4 2 8
输出
6
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
解析:
当k=0时,从n个中选出不相同的数,统计不相同的数有多少个。
当k>0时,当选中了i时,就不能选中i+k,所以要进行分组求解,i、i+k、i+2k、i+3k……一组。
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
const ll MAX = 1e6;
const ll M = 1e9 + 7;
ll a[MAX];//存储输入
ll dp[MAX];//动态规划
ll ans[MAX];//输入的每个数有几个
ll v[MAX];//存储这一组对应元素的个数
int main()
{
ll n, k;
cin >> n>>k;
ll sum = 0,mx=-1;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mx = max(mx, a[i]);//找输入的最大值
if (ans[a[i]] == 0)//首次为0时 一个新的元素
{
sum++;
}
ans[a[i]]++;//相同元素+1
}
if (k == 0)
{
cout << sum << endl;
}
else
{
sum = 0;
//分组{0,k,2k,3k,4k}{1,k+1,2k+1,3k+1}
for (int i = 0; i < k; i++)
{
ll s = 1;//当前组中每个元素有几个
for (int j = i; j <=mx; j+=k)
{
v[s++] = ans[j];
}
dp[1] = v[1];
for (int j = 2; j < s; j++)
{
dp[j] = max(dp[j - 1], dp[j - 2] + v[j]);
}
sum += dp[s - 1];//一组中最多有多少个
}
cout << sum << endl;
}
return 0;
}