皎月半洒花
2019-02-11 16:57:55
其实主要思想都差不多,但我发这篇
我们定义状态
这样定义状态的原因是:我们发现如果单纯用
转移的时候直接枚举有多少个
然后我们的代码特别短:
#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 1000020
using namespace std ; int N, M ;
int Sum[MAXN], dp[MAXN][3][3], i, j, k, l ;
inline int qrd(){
register int k = 0 ; char c = getchar() ;
while (c < '0' || c > '9') c = getchar() ;
while (c <= '9' && c >= '0') k = (k << 1) + (k << 3) + c - 48, c = getchar() ;
return k ;
}
int main(){
cin >> N >> M ;
memset(dp, -1, sizeof(dp)), dp[0][0][0] = 0 ;
for (i = 1 ; i <= N ; ++ i) Sum[ qrd() ] ++ ;
for (i = 1 ; i <= M ; ++ i){
for (j = 0 ; j < 3 ; ++ j)
for (k = 0 ; k < 3 ; ++ k)
for (l = 0 ; l < 3 ; ++ l)
if (Sum[i] < j + k + l) continue ;
else dp[i][k][l] = max(dp[i][k][l], dp[i - 1][j][k] + (Sum[i] - j - k - l)/3 + l) ;
}
cout << dp[M][0][0] << endl ; return 0 ;
}
闲扯一点:这个题楼主在当时并没有能够想出来……因为没有深刻思考其中的性质qaq