其他分享
首页 > 其他分享> > CF1110D Jongmah 题解

CF1110D Jongmah 题解

作者:互联网

Solution

设 \(f_{i,j,k}\) 表示考虑取值为 \(1\sim i\) 的牌,出现了 \(j\) 个 \([i-1,i,i+1]\),\(k\) 个 \([i,i+1,i+2]\)。

注意到 \(3\) 个 \([x-1,x,x+1]\) 能替换成 \([x-1,x-1,x-1],[x,x,x],[x+1,x+1,x+1]\),所以 \(f_{i,j,k}\) 中 \(0\le j,k\le 2\)。

转移的时候枚举 \(0\le l\le 2\),然后考虑 \(f_{i-1,l,j}\) 怎么转移到 \(f_{i,j,k}\):

红色的方框就是 \(f_{i,j,k}\) 比 \(f_{i-1,l,j}\) 多出来的部分,那么:

\[f_{i,j,k}=\max_{l=0}^2\left\{f_{i-1,l,j}+k+\left\lfloor\frac{cnt_i-j-k-l}3\right\rfloor\right\} \]

Code

#include<cstdio>
#include<algorithm>

const int N=1e6;

int n,m,cnt[N+10],f[N+10][3][3];

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int x;scanf("%d",&x);
		cnt[x]++;
	}
	for(int i=1;i<=m;i++)
		for(int j=0;j<=2;j++)
			for(int k=0;k<=2;k++)
				for(int l=0;l<=2;l++)
					if(cnt[i]>=j+k+l)
						f[i][j][k]=std::max(f[i][j][k],f[i-1][l][j]+(cnt[i]-j-k-l)/3+k);
	printf("%d\n",f[m][0][0]);
	return 0;
}

标签:cnt,le,int,题解,Jongmah,right,max,include,CF1110D
来源: https://www.cnblogs.com/registergen/p/cf1110d_solution.html