题目链接:https://codeforces.com/contest/1110/problem/D
题意
给出n个不超过m的序列,三个相同的数或者三个连续的数可以构成一个三元组,问这个序列最多可以构造出多少个三元组。
题解
对于一个数字i,[i,i+1,i+2]这样连续的序列最多不超过2个,因为一旦有3个,那就和[i,i,i],[i+1,i+1,i+1],[i+2,i+2,i+2] 这样没有差别了。
设dp[i][j][k]
:表示前i位里面有j个[i-1,i,i+1],k个[i,i+1,i+2]时三元组有多少个。
转移:
dp[i][j][k] = max{dp[i-1][t][j]+t+(C[i]-j-k-t)/3}
C[i]: 值为i的数有多少个。
代码
//https://codeforces.com/contest/1110/problem/D
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+6;
int a[maxn], dp[maxn][3][3];
int n,m;
int main() {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++i) {
int u;
scanf("%d", &u);
a[u]++;
}
memset(dp,-0x3f3f3f3f,sizeof dp);
dp[0][0][0] = 0;
for(int i = 1; i <= m; ++i)
for(int j = 0; j < 3; ++j)
for(int k = 0; k < 3; ++k)
for(int t = 0; t < 3; ++t)
if(a[i] >= j+k+t)
dp[i][k][t] = max(dp[i][k][t], dp[i-1][j][k]+j+(a[i]-j-k-t)/3);
cout << dp[m][0][0] << endl;
return 0;
}
/*
dp[i][j][k] : 前i个数中, 在有j个[i-1,i,i+1]和k个[i,i+1,i+2]的情况下符合条件的三元组有多少个。
dp[i][k][t] = max{dp[i-1][j][k]+j+(a[i]-j-k-t)/3} j:[i-2,i-1,i]
*/