[CTSC2007]动物园zoo

link

试题分析

发现每个小朋友最多只能看到$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;
}
View Code

 

posted @ 2018-12-18 18:26  siruiyang_sry  阅读(291)  评论(0编辑  收藏  举报