题意:给出一个序列,选出至多k组,每组的元素间相差不超过5,可以不包含所有元素,求最多能包含多少个元素。
题解:dp
先排序。
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]:前
i
i
i个元素分成
j
j
j组所能包含的最多元素数量。
然后对于第
i
i
i个元素:
选:
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
dp[i][j] = dp[i - 1][j]
dp[i][j]=dp[i−1][j]。
不选:
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
−
1
]
,
d
p
[
p
o
s
−
1
]
[
j
−
1
]
+
i
−
p
o
s
+
1
)
dp[i][j] = max(dp[i - 1][j - 1],dp[pos - 1][j - 1] + i - pos + 1)
dp[i][j]=max(dp[i−1][j−1],dp[pos−1][j−1]+i−pos+1)。
p
o
s
pos
pos保存从第
i
i
i个元素往前,差值不超过5的最远位置。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
int n, k, a[5555], dp[5555][5555];
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
sort(a + 1, a + n + 1);
int pos = 1, ans = 0;
for (int i = 1; i <= n; i++) {
while (pos < i && a[i] - 5 > a[pos]) pos++;
for (int j = 1; j <= min(i, k); j++) {
dp[i][j] = max(dp[i - 1][j], dp[pos - 1][j - 1] + i - pos + 1);
ans = max(ans, dp[i][j]);
}
}
printf("%d\n",ans);
return 0;
}