Jongmah Codeforces - 1110D
https://codeforces.com/contest/1110/problem/D
注意到3个完全相同的"连续三张"相当于3个"三张一样的牌",所以可以当成任意一种"连续三张"最多出2个,其他都出"三张一样的牌"
然后胡乱dp就可以了。。
然而我比赛时候30+分钟死活调不出来,成功爆零
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pb push_back 10 typedef long long ll; 11 typedef unsigned long long ull; 12 typedef pair<int,int> pi; 13 int ans[1000011][3][3]; 14 int n,m,anss,num[1000011]; 15 //用"顺子j"表示顺子(j-2,j-1,j) 16 //ans[i][j][k]表示位置i为止,顺子i取j个,顺子i-1取k个,且合法时最大答案 17 int main() 18 { 19 int i,j,k,l,t; 20 scanf("%d%d",&n,&m); 21 for(i=1;i<=n;++i) 22 { 23 scanf("%d",&t); 24 ++num[t]; 25 } 26 if(m>=3) 27 { 28 memset(ans,192,sizeof(ans)); 29 ans[2][0][0]=0; 30 for(i=3;i<=m;++i) 31 { 32 for(j=0;j<=2;++j) 33 { 34 for(k=0;k<=2;++k) 35 { 36 for(l=0;l<=2;++l) 37 { 38 if( (num[i-2]>=l+k+j) && (num[i-1]>=k+j) && (num[i]>=j) ) 39 { 40 ans[i][j][k]=max(ans[i][j][k],ans[i-1][k][l]+j+(num[i-2]-l-k-j)/3); 41 } 42 } 43 } 44 } 45 } 46 for(j=0;j<=2;++j) 47 for(k=0;k<=2;++k) 48 anss=max(anss,ans[m][j][k]+(num[m]-j)/3+(num[m-1]-j-k)/3); 49 /* 50 for(i=3;i<=m;++i) 51 { 52 memset(tmp,192,sizeof(tmp)); 53 for(j=0;j<=min(2,num[i-1]);++j) 54 { 55 tmp[j][j]=ans[i-1][j][j]; 56 for(k=j+1;k<=min(6,num[i-2]);++k) 57 { 58 tmp[j][k]=max(tmp[j][k-1],ans[i-1][j][k]+(num[i-2]-k)/3); 59 } 60 } 61 for(j=0;j<=min(2,num[i]);++j) 62 { 63 for(k=j;k<=min(6,num[i-1]);++k) 64 { 65 //ans[i-1][k-j][?],?<=num[i-2]-j 66 if(num[i-2]>=j && k-j<=2 && num[i-2]-j<=6)//&& (k-j)<=(num[i-2]-j) ) 67 ans[i][j][k]=tmp[k-j][num[i-2]-j]+j; 68 69 for(l=0;l<=num[i-2]-j;++l) 70 { 71 ans[i][j][k]=max(ans[i][j][k], 72 ans[i-1][k-j][l]+j); 73 } 74 } 75 } 76 } 77 for(j=0;j<=num[m];++j) 78 for(k=j;k<=num[m-1];++k) 79 anss=max(anss,ans[m][j][k]+(num[m]-j)/3+(num[m-1]-k)/3); 80 */ 81 } 82 else 83 anss=num[1]/3+num[2]/3; 84 printf("%d",anss); 85 return 0; 86 }