\(\color{#0066ff}{ 题目描述 }\)
你在玩一个叫做 Jongmah 的游戏,你手上有 \(n\) 个麻将,每个麻将上有一个在 \(1\) 到 \(m\) 范围内的整数 \(a_i\)。
为了赢得游戏,你需要将这些麻将排列成一些三元组,每个三元组中的元素是相同的或者连续的。如 \(7,7,7\) 和 \(12,13,14\) 都是合法的。你只能使用手中的麻将,并且每个麻将只能使用一次。
请求出你最多可以形成多少个三元组。
\(\color{#0066ff}{输入格式}\)
第一行为n,m为麻将个数和范围
接下来一行n个整数表示麻将
\(\color{#0066ff}{输出格式}\)
输出最多形成多少个三元组
\(\color{#0066ff}{输入样例}\)
10 6
2 3 3 3 4 4 4 5 5 6
12 6
1 5 3 3 3 4 3 5 3 2 3 3
13 5
1 1 5 1 2 3 3 2 4 2 3 4 5
\(\color{#0066ff}{输出样例}\)
3
3
4
\(\color{#0066ff}{数据范围与提示}\)
\(1\le n,m\le 10^6\),\(1\le a_i\le m\)
\(\color{#0066ff}{ 题解 }\)
-------p_b_p_b
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e6 + 100;
int f[maxn][5][5], cnt[maxn];
int n, m;
int main() {
n = in(), m = in();
for(int i = 1; i <= n; i++) cnt[in()]++;
memset(f, -1, sizeof(f));
f[0][0][0] = 0;
for(int i = 0; i <= std::min(4, cnt[1]); i++) f[1][i][0] = (cnt[1] - i) / 3;
for(int i = 2; i <= m; i++) {
for(int j = 0; j <= 4; j++) {
if(j > cnt[i]) break;
for(int k = 0; k <= 4; k++) {
if(k > cnt[i - 1]) break;
for(int l = 0; l <= 2; l++) {
if(j + l > cnt[i] || k + l > cnt[i - 1] || l > cnt[i - 2] || k + l > 4) break;
f[i][j][k] = std::max(f[i][j][k], f[i - 1][k + l][l] + (cnt[i] - j - l) / 3 + l);
}
}
}
}
printf("%d\n", f[m][0][0]);
return 0;
}