Codeforces Contest 1110 problem D Jongmah——三种状态的dp

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
inputCopy
10 6
2 3 3 3 4 4 4 5 5 6
outputCopy
3
inputCopy
12 6
1 5 3 3 3 4 3 5 3 2 3 3
outputCopy
3
inputCopy
13 5
1 1 5 1 2 3 3 2 4 2 3 4 5
outputCopy
4
Note
In the first example, we have tiles 2,3,3,3,4,4,4,5,5,6. We can form three triples in the following way: 2,3,4; 3,4,5; 4,5,6. Since there are only 10 tiles, there is no way we could form 4 triples, so the answer is 3.

In the second example, we have tiles 1, 2, 3 (7 times), 4, 5 (2 times). We can form 3 triples as follows: 1,2,3; 3,3,3; 3,4,5. One can show that forming 4 triples is not possible.

题意:

给你一个数组,x x x 或者 x x+1 x+2可以组成一种结果,每个数字只能用一次,问你最后最多能有多少个。

题解:

一开始开了二维的,但是做到后面错了,看别人的题解才发现需要用三维的记录,因为自己没想到大于等于3个可以直接放到dp里面。 dp[i][j][k]表示的是,在第i个位置,j,k的状态下有多少个结果。j表示的是当前位置在最前面的情况,就是 i i+1 i+2 这种,k表示的是 i-1 i i+1这种情况,l表示的是 i-2 i-1 i 这种情况 由于每个数的第l 种情况可以用下一个数的第k种情况表示,所以冗余了,就记录每个数在第一位和第二位的情况就好了,那么状态转移方程就是
dp[i][k][l]=max(dp[i][k][l],dp[i-1][j][k]+l+(cnt[i]-j-k-l)/3);
意思就是 当前位置在中间和在右边的情况是上一个位置在左边和在中间的情况转移过来的,由于这个位置在最右边的情况是l,所以加上l,再加上剩下的情况/3构成一组。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int dp[N][5][5],cnt[N];
int main()
{
    int n,m,a;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a),cnt[a]++;
    for(int i=1;i<=m;i++)
    {
        for(int j=0;j<3;j++)
        {
            for(int k=0;k<3;k++)
            {
                for(int l=0;l<3&&j+k+l<=cnt[i];l++)
                    dp[i][k][l]=max(dp[i][k][l],dp[i-1][j][k]+l+(cnt[i]-j-k-l)/3);
            }
        }
    }
    printf("%d\n",dp[m][0][0]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/88298291
今日推荐