Codeforces Global Round 1 D. Jongmah

題目鏈接:D. Jongmah

題目大意:一些數字,有兩種方式組成一個三元組(三角形),[x,x,x],[x,x+1,x+2],(刻子或順子)每個數字只能用一次,求最多組成多少三元組。

思路:顯然3個順子和3個刻子對結果的貢獻一樣,即3組[i,i+1,i+2]和[i,i,i],[i+1,i+1,i+1],[i+2,i+2,i+2]對答案的貢獻一樣。所以我們不妨假設每個以i爲開頭的三元組[i,i+1,i+2]不超過2個。設dp[i][t1][t2]表示前i個數值中,以有t1個三元組[i,i+1,i+2],t2個三元組[i-1i,i+1].(這裏對每個數值i只考慮兩種三元組,而不考慮[i-2,i-1,i]防止重複。)

轉移時枚舉第三種三元組情況即可,即枚舉[i-2,i-1,i]的數量t3,dp[i][t1][t2]=max(dp[i][t1][t2],dp[i][t2][t3]+(cnt[i]-t1-t2-t3)/3+t3);

代碼(採用了滾動數組):

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
typedef long long ll;
using namespace std;
#define INF 0x3f3f3f3f
const int mod=1e9+7;
const int maxn=1e6+10;
int n,m,cnt[maxn];
int dp[2][3][3];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int a;
		scanf("%d",&a);
		cnt[a]++;
	}
	memset(dp,-1,sizeof(dp));
	dp[0][0][0]=0; 
	int tmp=1;
	for(int i=1;i<=m;i++){
		memset(dp[tmp],-1,sizeof(dp[tmp]));
		for(int t1=0;t1<3;t1++)
			for(int t2=0;t2<3;t2++)
				for(int t3=0;t3<3;t3++){
					if(cnt[i]-t1-t2-t3<0||dp[tmp^1][t2][t3]==-1)continue;
					dp[tmp][t1][t2]=max(dp[tmp][t1][t2],dp[tmp^1][t2][t3]+(cnt[i]-t1-t2-t3)/3+t3);
				}
		tmp^=1;
	}
	printf("%d\n",dp[tmp^1][0][0]);
	return 0;
}	

 

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