[CTSC2007]动物园zoo
试题分析
发现每个小朋友最多只能看到$5$个动物所以考虑状压$dp$。我们定义$f(i,j)$为第$i$个位置从此往后$5$个人的最喜欢数量。所以只要预处理出对于每个点从后$5$个会让多少小朋友高兴即可
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int N=50001; const int M=50001; int n,m,cal[M][33],f[N][33]; int maxn; int main(){ n=read(),m=read(); for(int i=1;i<=m;i++){ int s=read(),seccnt=read(),hapcnt=read(); int hap=0,sec=0; for(int j=1;j<=seccnt;j++){ int x=read();x=((x-s)%n+n)%n; sec|=(1<<(x)); } for(int j=1;j<=hapcnt;j++){ int x=read();x=((x-s)%n+n)%n; hap|=(1<<(x)); } for(int j=0;j<32;j++) if((j&hap)||((sec&j)!=sec)) { cal[s][j]++; } } for(int i=0;i<32;i++){ memset(f,-127/3,sizeof(f)); f[0][i]=0; for(int j=1;j<=n;j++){ for(int z=0;z<32;z++) f[j][z]=max(f[j-1][(z&15)<<1],f[j-1][((z&15)<<1)|1])+cal[j][z]; } maxn=max(maxn,f[n][i]); } cout<<maxn; }