bzoj1151

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1151

状压DP,枚举前面4个,使得环型变线型。
#include<cstdio>

#include<cstdlib>

#include<iostream>

#include<fstream>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<queue>

#include<stack>

#include<map>

#include<utility>

#include<set>

#include<bitset>

#include<vector>

#include<functional>

#include<deque>

#include<cctype>

#include<climits>

#include<complex>

//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj

 

using namespace std;



typedef long long LL;

typedef double DB;

typedef pair<int,int> PII;

typedef complex<DB> CP;



#define mmst(a,v) memset(a,v,sizeof(a))

#define mmcy(a,b) memcpy(a,b,sizeof(a))

#define re(i,a,b)  for(i=a;i<=b;i++)

#define red(i,a,b) for(i=a;i>=b;i--)

#define fi first

#define se second

#define m_p(a,b) make_pair(a,b)

#define SF scanf

#define PF printf

#define two(k) (1<<(k))



template<class T>inline T sqr(T x){return x*x;}

template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}

template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}



const DB EPS=1e-9;

inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}

const DB Pi=acos(-1.0);



inline int gint()

  {

        int res=0;bool neg=0;char z;

        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());

        if(z==EOF)return 0;

        if(z=='-'){neg=1;z=getchar();}

        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());

        return (neg)?-res:res; 

    }

inline LL gll()

  {

      LL res=0;bool neg=0;char z;

        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());

        if(z==EOF)return 0;

        if(z=='-'){neg=1;z=getchar();}

        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());

        return (neg)?-res:res; 

    }



const int maxN=10000;

const int maxC=50000;



#define wei(v,k) (((v)>>(k-1))&1)



int N,C;

struct Tkid

  {

      int pos,afraid,love;

        inline void input()

          {

              int i,F,L;

                pos=gint()+4;F=gint();L=gint();

                afraid=0;re(i,1,F){int t=gint();if(pos>N && t<=4)t+=N;afraid|=two(pos-t);}

                love=0;re(i,1,L){int t=gint();if(pos>N && t<=4)t+=N;love|=two(pos-t);}

            }

        inline int happy(int state){return ((~state)&love) || (state & afraid);} 

    }kid[maxC+100];



int F[maxN+100][two(5)+10];

int ans;



int main()

  {

      freopen("bzoj1151.in","r",stdin);

      freopen("bzoj1151.out","w",stdout);

      int i,j,l;

      N=gint();C=gint();

      re(i,1,C)kid[i].input();

      int S;

      re(S,0,two(4)-1)

        {

          mmst(F,-1);

          F[4][S]=0;

            int head=1,tail;

            re(i,5,N)re(j,0,two(5)-1)re(l,0,1)

              {

                  while(head<=C && kid[head].pos<i)head++;

                  if(F[i-1][j]==-1)continue;

                  int k,t;

                  k=(j*2+l)%two(5);

                  t=F[i-1][j];

                  for(tail=head;tail<=C && kid[tail].pos==i;tail++)if(kid[tail].happy(k))t++;

                  upmax(F[i][k],t);

              }

            re(i,N+1,N+4)re(j,0,two(5)-1)

              {

                  while(head<=C && kid[head].pos<i)head++;

                  if(F[i-1][j]==-1)continue;

                  int k,t;

                  k=(j*2+wei(S,5+N-i))%two(5);

                  t=F[i-1][j];

                  for(tail=head;tail<=C && kid[tail].pos==i;tail++)if(kid[tail].happy(k))t++;

                  upmax(F[i][k],t);

              }

            re(j,0,two(5)-1)upmax(ans,F[N+4][j]);

          }

        cout<<ans<<endl;

        return 0;

    }
View Code

 

你可能感兴趣的:(ZOJ)