\(\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

CF1110D Jongmah_干货

#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;
}
----olinr