BZOJ 1151: [CTSC2007]动物园zoo

因为有环,枚举前四位,每次做一次状压DP

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[50005],b[5],G[10005][32],F[10005][32];
int main(){
	scanf("%d%d",&n,&m);
	for (int i=1; i<=m; i++){
		scanf("%d",&a[i]);
		int N,M;
		scanf("%d%d",&N,&M);
		int X=0,Y=0;
		for (int j=0; j<N; j++) scanf("%d",&b[j]);
		for (int j=0; j<N; j++) X|=(1<<(b[j]+n-a[i])%n);
		for (int j=0; j<M; j++) scanf("%d",&b[j]);
		for (int j=0; j<M; j++) Y|=(1<<(b[j]+n-a[i])%n);
		for (int j=0; j<(1<<5); j++)
			if ((j&X) || (31^j)&Y) G[a[i]][j]++;
	}
	int ans=0;
	for (int i=0; i<(1<<4); i++){
		for (int k=0; k<(1<<5); k++) F[0][k]=-1e9;
		F[0][i<<1]=0;
		for (int j=1; j<=n; j++)
			for (int k=0; k<(1<<5); k++)
				F[j][k]=max(F[j-1][(k&15)<<1],F[j-1][(k&15)<<1|1])+G[j][k];
		ans=max(ans,max(F[n][i<<1],F[n][i<<1|1]));
	}
	printf("%d
",ans);
	return 0;
}

  

原文地址:https://www.cnblogs.com/silenty/p/9886118.html