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\n",ans); return 0; }