Codeforces Global Round 1 D - Jongmah

  • 題目鏈接:http://codeforces.com/contest/1110/problem/D
  • 題意:給你兩個整數n、m,表示:給你n個整數,每個整數的範圍都在[1 , m]。現在可以將三個數值相同的數(如:777)或者三個數值連續的數(如:123,但112不算)組成一個三元組,問這n個數最多能組多少個三元組?(每個數最多隻能用在一個三元組中)
  • 因爲3個連續三元組可以轉換成三個相同數值的三元組,所以對於一種連續三元組,其個數最多有2個。那麼對於一個數值等於 i的數(可能有多個數的數值等於i),其除了組成相同數的三元組以外,組成了x個[i-2, i-1, i],y個[i-1, i, i+1], z個[i, i+1, i+2] (0<= x,y,z <=2),這是對於數值i的所有情況,也就是對於數值i的所有可能的狀態。那麼設dp[i][y][z]表示在組成y個[i-1, i, i+1], z個[i, i+1, i+2] 的狀態下,在只使用小於等於數值i的數時(1<= i <= m)(也就是dp[i][y][z]的值並沒有算上這 y+z 個三元組),最多組成了多少個三元組
  • 注意點:要把dp初始化爲 負無窮,表示此種情況不存在。令dp[0][0][0] = 0,表示此種情況存在,但數量爲0。
#include <bits/stdc++.h>
#define pi acos(-1.0 )
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;//4e18 ~= 2^62
const int maxn =1e6 + 10;
const LL mod = 1e9+7;

int a[maxn], dp[maxn][3][3];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    int tmp;
    for(int i=1; i<=n; i++){
        scanf("%d", &tmp);
        a[tmp]++;
    }
    memset(dp, -INF, sizeof(dp));
    dp[0][0][0] = 0;
    for(int i=1; i<=m; i++){
        for(int x=0; x<3; x++){
            for(int y=0; y<3; y++){
                for(int z=0; z<3; z++){
                    if(a[i] < x+y+z) continue;
                    dp[i][y][z] = max(dp[i][y][z], dp[i-1][x][y] + (a[i]-x-y-z)/3 + x);
                }
            }
        }
    }
    printf("%d\n", dp[m][0][0]);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章