codeforces 1110D. Jongmah

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≤n,m≤106) — the number of tiles in your hand and the number of tiles types.
The second line contains integers a1,a2,…,an(1≤ai≤m), where ai 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

Output

3

Input

12 6
1 5 3 3 3 4 3 5 3 2 3 3

Output

3

Input

13 5
1 1 5 1 2 3 3 2 4 2 3 4 5

Output

4

刚开始看到这个题的时候,我是死活不会向DP这个方向想的,区间也能DP,假的吧。然后我就错了T_T。。在看完题解和两位大佬的帮助下,我最后终于明白了这玩意,还挺好用。
首先我们可以知道,对于任意的{x,x+1,x+2}X3可以分解成{x,x,x}X1 {x+1,x+1,x+1}X1和{x+2,x+2,x+2}X1,也就是说,这样连续型三元组的个数不会超过2个。
对于任意位置i,我们可以组成它的连续型和相同三元组,我们可以枚举所有的连续型三元组的个数,进而确定相同三元组的个数。


#include <stdio.h>
#include <climits>
#include <cstring>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
#include <string>

#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<=finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

int dp[1000005][3][3];
int num[1000005];
inline int Min(int a,int b,int c);
int main(){
    ios::sync_with_stdio(false);

    int N,M;
    cin>>N>>M;
    mem(num,0);
    int n,star=INT_MAX;
    rep(i,0,N-1){
        cin>>n;

        star=min(star,n);
        num[n]++;
    }

    mem(dp,0);
    dp[star][0][0]=num[star]/3;
    dp[star][1][0]=(num[star]-1)/3;
    dp[star][2][0]=(num[star]-2)/3;
    rep(i,star,M){
        rep(j,0,min(2,Min(num[i],num[i+1],num[i+2]))){
            rep(k,0,min(2,Min(num[i-1],num[i]-j,(num[i+1]-j)) )){
                rep(l,0,min(2,Min(num[i-2],(num[i-1]-k),(num[i]-j-k)) )){
                    dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+l+(num[i]-j-k-l)/3);
                }
            }
        }
    }
    cout<<dp[M][0][0]<<endl;

    re 0;
}
inline int Min(int a,int b,int c){
    re min(min(a,b),c);
}

发布了161 篇原创文章 · 获赞 170 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/white_156/article/details/89149326