# Codeforces 1110 D. Jongmah （dp）

## Description

You are playing a game of Jongmah. You don’t need to know the rules to solve this problem. You have $n$ tiles in your hand. Each tile has an integer between $1$ and $m$ written on it.

To win the game, you will need to form some number of triples. Each triple consists of three tiles, such that the numbers written on the tiles are either all the same or consecutive. For example, 7,7,7 is a valid triple, and so is 12,13,14, but 2,2,3 or 2,4,6 are not. You can only use the tiles in your hand to form triples. Each tile can be used in at most one triple.

To determine how close you are to the win, you want to know the maximum number of triples you can form from the tiles in your hand.

## Input

The first line contains two integers integer $n$ and $m$ $(1 \le n,m \le 10^6)$ — the number of tiles in your hand and the number of tiles types.

The second line contains integers $a_1,a_2,…,a_n$ $(1 \le a_i \le m)$, where $a_i$ denotes the number written on the $i$-th tile.

## Output

Print one integer: the maximum number of triples you can form.

## Examples input

10 6
2 3 3 3 4 4 4 5 5 6


## Examples output

3


## AC 代码

#include <bits/stdc++.h>
#define IO                       \
ios::sync_with_stdio(false); \
cin.tie(0);                  \
cout.tie(0);
#define mem(a, x) memset(a, x, sizeof(a))
#define per(x, a, b) for (int x = a; x <= b; x++)
#define rep(x, a, b) for (int x = a; x >= b; x--)

using namespace std;
typedef long long LL;
typedef pair<int, pair<int, int>> P;
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n, m;
int a[maxn];

LL dp[maxn][3][3];

void solve() {
mem(dp, 0);
LL ans = 0;
for (int i = 0; i < 3; i++) {
if (min({a[1], a[2], a[3]}) < i)
continue;
dp[1][0][i] = (a[1] - i) / 3;
ans = max(ans, dp[1][0][i]);
}
for (int i = 1; i < maxn - 5; i++) {
for (int l = 0; l < 3; l++) {         // a[i]
for (int j = 0; j < 3; j++) {     // a[i+1]
for (int k = 0; k < 3; k++) { // a[i+2]
if (a[i - 1] < l || a[i] < l + j || a[i + 1] < l + j + k ||
a[i + 2] < j + k || a[i + 3] < k)
continue;
dp[i + 1][j][k] =
max(dp[i + 1][j][k],
dp[i][l][j] + j + (a[i + 1] - l - j - k) / 3);
ans = max(ans, dp[i + 1][j][k]);
}
}
}
}
cout << ans << endl;
}

int main() {
#ifdef LOCAL_IM0QIANQIAN
freopen("test.in", "r", stdin);
//    freopen("test.out", "w", stdout);
#else
IO;
#endif // LOCAL_IM0QIANQIAN

while (cin >> n >> m) {
mem(a, 0);
for (int i = 0; i < n; i++) {
int x;
cin >> x;
a[x]++;
}
solve();
}
return 0;
}