1. 程式人生 > >bzoj 1151 [CTSC2007]動物園zoo

bzoj 1151 [CTSC2007]動物園zoo

最大 utc led class esp cts i++ getc load

Description

新建的圓形動物園是亞太地區的驕傲。圓形動物園坐落於太平洋的一個小島上,包含一大圈圍欄,每個圍欄裏有一 種動物。如下圖所示: 技術分享圖片 你是動物園的公共主管。你要做的是,讓每個來動物園的人都盡可能高興。今天有一群小朋友來動物園參觀,你希 望能讓他們在動物園度過一段美好的時光。但這並不是一件容易的事——有的動物有一些小朋友喜歡,有的動物有 一些小朋友害怕。如,Alex 喜歡可愛的猴子和考拉,而害怕擁牙齒鋒利的獅子。而Polly 會因獅子有美麗的鬃毛 而喜歡它,但害怕有臭味的考拉。你可以選擇將一些動物從圍欄中移走以使得小朋友不會害怕。但你不能移走所有 的動物,否則小朋友們就沒有動物可看了。每個小朋友站在大圍欄圈的外面,可以看到連續的 5 個圍欄。你得到 了所有小朋友喜歡和害怕的動物信息。當下面兩處情況之一發生時,小朋友就會高興: 至少有一個他害怕的動物被移走 至少有一個他喜歡的動物沒被移走 例如,考慮下圖中的小朋友和動物: 技術分享圖片
假如你將圍欄 4 和 12 的動物移走。Alex 和 Ka-Shu 將很高興,因為至少有一個他們害怕的動物被移走了。這也 會使 Chaitanya 高興,因為他喜歡的圍欄 6 和8 中的動物都保留了。但是,Polly 和 Hwan 將不高興,因為他們 看不到任何他們喜歡的動物,而他們害怕的動物都還在。這種安排方式使得三個小朋友高興。現在,換一種方法, 如果你將圍欄 4 和 6 中的動物移走,Alex 和 Polly 將很高興,因為他們害怕的動物被移走了。Chaitanya 也會 高興,雖然他喜歡的動物 6被移走了,他仍可以看到圍欄 8 裏面他喜歡的動物。同樣的 Hwan 也會因可以看到自 己喜歡的動物 12 而高興。唯一不高興的只有 Ka-Shu。如果你只移走圍欄 13 中的動物,Ka-Shu 將高興,因為有 一個他害怕的動物被移走了,Alex, Polly, Chaitanya 和 Hwan 也會高興,因為他們都可以看到至少一個他們喜 歡的動物。所以有 5 個小朋友會高興。這種方法使得了最多的小朋友高興。

Input

輸入的第一行包含兩個整數N, C,用空格分隔。 N是圍欄數(10≤N≤10 000),C是小朋友的個數(1≤C≤50 000)。 圍欄按照順時針的方向編號為1,2,3,…,N。 接下來的C行,每行描述一個小朋友的信息, 以下面的形式給出: E F L X1 X2 … XF Y1 Y2 … YL 其中: E表示這個小朋友可以看到的第一個圍欄的編號(1≤E≤N), 換句話說,該小朋友可以看到的圍欄為E, E+1, E+2, E+3, E+4。 註意,如果編號超過N將繼續從1開始算。 如:當N=14, E=13時,這個小朋友可以看到的圍欄為13,14,1, 2和3。 F表示該小朋友害怕的動物數。 L表示該小朋友喜歡的動物數。 圍欄X1, X2, …, XF 中包含該小朋友害怕的動物。 圍欄Y1, Y2, …, YL 中包含該小朋友喜歡的動物。 X1, X2, …, XF, Y1, Y2, …, YL是兩兩不同的整數, 而且所表示的圍欄都是該小朋友可以看到的。 小朋友已經按照他們可以看到的第一個圍欄的編號從小到大的順序排好了 (這樣最小的E對應的小朋友排在第一個,最大的E對應的小朋友排在最後一個)。 註意可能有多於一個小朋友對應的E是相同的。

Output

僅輸出一個數,表示最多可以讓多少個小朋友高興

Sample Input

10 10
1 1 1 3 2
2 1 0 4
3 1 1 5 6
4 1 1 7 6
5 1 0 6
6 1 2 9 8 10
7 1 0 10
8 1 0 8
9 1 1 1 2
10 1 0 2

Sample Output

10
思路:枚舉前5個的狀態考慮環的情況,然後後面做二維狀壓f[i][j]表示從第i個圍欄開始的5個狀態是j。 時間復雜度O(2^10*C),感覺不會超時,但是我的寫法居然常數特別大,orz
  1 #include<bits/stdc++.h>
  2 using namespace std; 
  3 #define F(i,a,b) for(int i=(a);i<=(b);i++)
  4 #define D(i,a,b) for(int i=a;i>=b;i--) 
  5 #define ms(i,a)  memset(a,i,sizeof(a)) 
  6 
  7 template <class T> void read(T &x){
  8     x=0; int w=0; char c=getchar(); 
  9     while (c<0 || c>9) c=getchar(); 
 10     while (c>=0 && c<=9) x=(x<<3)+(x<<1)+(c^48),c=getchar(); 
 11     if(w) x=-x;  
 12 }
 13 
 14 template <class T> void write(T x){
 15     if(x<0) x=-x,putchar(-); 
 16     if(x>9) write(x/10); 
 17     putchar(x%10+48); 
 18 }
 19 
 20 template <class T> void writeln(T x){
 21     write(x); 
 22     putchar(\n); 
 23 }
 24 template <class T> void inline chkmin(T &x,T y){ x=min(x,y);}
 25 template <class T> void inline chkmax(T &x,T y){ x=max(x,y);}
 26 
 27 int const maxn=50003; 
 28 int const maxc=50003; 
 29 
 30 struct Edge{
 31     int to,nt; 
 32 }E[maxn<<2];  
 33 int cnt,H[maxc],n,c,st[maxc],dp[10003][1<<5],ans,xv[maxn][5],yv[maxn][5],sum[maxn]; 
 34 int e[maxc],f[maxc];   
 35 
 36 void add(int a,int b){
 37     E[cnt]=(Edge){b,H[a]}; H[a]=cnt++; 
 38 }
 39 
 40 void solve(int pre){
 41     F(i,1,n-5) F(j,0,31){
 42         int v=j>>1; 
 43         int ad=0;  
 44         if(dp[i][j]+sum[i+1]>dp[i+1][v])
 45         for(int t=H[i+1];t!=-1;t=E[t].nt){
 46             int K=E[t].to; 
 47             int check1=0,check2=0; 
 48             for(int p=0;p<5;p++)if(xv[K][p]){
 49                 if((1<<p) & v) check1=1;  
 50                 if(check1) break;  
 51             }
 52             if(!check1)
 53             for(int p=0;p<5;p++)if(yv[K][p]){
 54                 if( (1<<p) & ~v) check2=1; 
 55                 if (check2) break;  
 56             }
 57             ad+=check1 ||  check2; 
 58         }
 59         chkmax(dp[i+1][v],dp[i][j]+ad);  
 60         v=(j>>1)+16;  
 61         ad=0;  
 62         if(dp[i][j]+sum[i+1]>dp[i+1][v])  
 63         for(int t=H[i+1];t!=-1;t=E[t].nt){
 64             int K=E[t].to;  
 65             int check1=0,check2=0; 
 66             for(int p=0;p<5;p++)if(xv[K][p]){
 67                 if((1<<p) & v) check1=1;  
 68                 if(check1) break;  
 69             }
 70             if(!check1)
 71             for(int p=0;p<5;p++) if(yv[K][p]) {
 72                 if( (1<<p) & ~v) check2=1; 
 73                 if(check2) break;  
 74             }
 75             ad+=check1 ||  check2; 
 76         }
 77         chkmax(dp[i+1][v],dp[i][j]+ad);  
 78     }
 79     int g=0; 
 80     int ret=0;  
 81     F(j,0,31){
 82         int ad=0;
 83         F(i,n-3,n){
 84             int num=i-n+4; 
 85             int v=(j>>num)+(pre&((1<<num)-1))*(1<<(5-num));  
 86             for(int t=H[i];t!=-1;t=E[t].nt){
 87                 int K=E[t].to;  
 88                 int check1=0,check2=0; 
 89                 for(int p=0;p<5;p++)if(xv[K][p]){
 90                     if((1<<p) & v)  check1=1;
 91                 }
 92                 if(!check1) 
 93                 for(int p=0;p<5;p++)if(yv[K][p]){
 94                     if((1<<p) & ~v) check2=1;  
 95                 }
 96                 ad+=check1 ||  check2;  
 97             } 
 98         }
 99         chkmax(ret,dp[n-4][j] + ad);  
100     }
101     chkmax(ans,ret);  
102 }
103 int main(){
104     scanf("%d%d",&n,&c);  
105     ms(-1,H); 
106     F(i,1,c){
107         scanf("%d",&st[i]); 
108         sum[st[i]]++;  
109         add(st[i],i); 
110         int x,y; 
111         scanf("%d%d",&x,&y);  
112         while (x--){
113             int k; scanf("%d",&k); 
114             if(k<st[i]) k=n+k;
115             xv[i][k-st[i]]=1; 
116         }
117         while (y--){
118             int k; scanf("%d",&k); 
119             if(k<st[i]) k=n+k; 
120             yv[i][k-st[i]]=1;  
121         }
122     }
123     F(i,0,31){
124         ms(0,dp);  
125         for(int t=H[1];t!=-1;t=E[t].nt){
126             int k=E[t].to;    
127             int check1=0; 
128             for(int p=0;p<5;p++)if(xv[k][p]) { 
129                 if ( (1<<p) & i)  check1=1;  
130             }
131             int check2=0; 
132             for(int p=0;p<5;p++)if(yv[k][p]) {
133                 if( (1<<p) & ~i) check2=1;  
134             } 
135             dp[1][i]+=check1 || check2; 
136         }
137         solve(i);  
138     }
139     cout<<ans<<endl; 
140     return 0; 
141 }
142 
143 
144 
145 /* 
146 14 5
147 2 1 2 4 2 6
148 3 1 1 6 4
149 6 1 2 9 6 8
150 8 1 1 9 12
151 12 3 0 12 13 2
152 
153 */ 

bzoj 1151 [CTSC2007]動物園zoo