CF1110D Jongmah

(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}{数据范围与提示})

(1le n,mle 10^6)(1le a_ile 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
", f[m][0][0]);
	return 0;
}
原文地址:https://www.cnblogs.com/olinr/p/10360154.html