1. 程式人生 > >BZOJ2331: [SCOI2011]地板

BZOJ2331: [SCOI2011]地板

getc AC and gif define LG printf fine nbsp

$n*m \leq 100$的地板,問在空地鋪$L$型磚的方案數。空地一定要鋪,非空地一定不鋪。對某個數取模。

直接插頭DP。插頭分三類,空,沒拐彎,有拐彎。轉移慢慢分。

技術分享圖片
  1 //#include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 //#include<time.h>
  5 //#include<complex>
  6 #include<algorithm>
  7 #include<stdlib.h>
  8 using namespace
std; 9 10 #define LL long long 11 int qread() 12 { 13 char c; int s=0; while ((c=getchar())<0 || c>9); 14 do s=s*10+c-0; while ((c=getchar())>=0 && c<=9); return s; 15 } 16 17 //Pay attention to ‘-‘ and LL of qread!!!! 18 19 int n,m; 20 const int mod=20110520
; 21 bool mp[111][111]; 22 23 #define maxn 1000007 24 int first[maxn],Next[maxn],ans[2][maxn],cur,state[2][maxn],len[2]; 25 void insert(int s,int v) 26 { 27 int h=s%maxn,y=cur^1; 28 for (int i=first[h];i;i=Next[i]) if (state[y][i]==s) 29 {ans[y][i]+=v; ans[y][i]-=ans[y][i]>=mod?mod:0
; return;} 30 state[y][++len[y]]=s; ans[y][len[y]]=v; 31 Next[len[y]]=first[h]; first[h]=len[y]; 32 } 33 34 int main() 35 { 36 scanf("%d%d",&n,&m); 37 if (n<m) 38 { 39 for (int i=1;i<=n;i++) 40 for (int j=1;j<=m;j++) 41 { 42 char c; while ((c=getchar())!=* && c!=_); 43 mp[j][i]=(c==*); 44 } 45 n^=m^=n^=m; 46 } 47 else 48 { 49 for (int i=1;i<=n;i++) 50 for (int j=1;j<=m;j++) 51 { 52 char c; while ((c=getchar())!=* && c!=_); 53 mp[i][j]=(c==*); 54 } 55 } 56 57 cur=1; insert(0,1); cur=0; 58 for (int i=1;i<=n;i++) 59 for (int j=1;j<=m;j++) 60 { 61 for (int k=1;k<=len[cur];k++) first[state[cur][k]%maxn]=0; 62 for (int k=1;k<=len[cur];k++) 63 { 64 int now=state[cur][k],p=now&3,q=(now>>2)&3,nk; 65 if (mp[i][j]==1) {if (p==0 && q==0) {nk=now>>2; insert(nk,ans[cur][k]);}} 66 else if (p==0 && q==0) 67 { 68 nk=(now>>2)|(1<<(m<<1)); insert(nk,ans[cur][k]); 69 if (j<m) 70 { 71 nk=(now>>2)|1; insert(nk,ans[cur][k]); 72 nk=(now>>2)|2|(2<<(m<<1)); insert(nk,ans[cur][k]); 73 } 74 } 75 else if (p==1 && q==0) 76 { 77 nk=(now>>2)|(2<<(m<<1)); insert(nk,ans[cur][k]); 78 if (j<m) {nk=(now>>2)|1; insert(nk,ans[cur][k]);} 79 } 80 else if (p==2 && q==0) 81 { 82 nk=(now>>2); insert(nk,ans[cur][k]); 83 if (j<m) {nk=(now>>2)|2; insert(nk,ans[cur][k]);} 84 } 85 else if (p==0 && q==1) 86 { 87 nk=((now>>2)^q)|(1<<(m<<1)); insert(nk,ans[cur][k]); 88 if (j<m) {nk=((now>>2)^q)|2; insert(nk,ans[cur][k]);} 89 } 90 else if (p==0 && q==2) 91 { 92 nk=((now>>2)^q)|(2<<(m<<1)); insert(nk,ans[cur][k]); 93 nk=(now>>2)^q; insert(nk,ans[cur][k]); 94 } 95 else if (p==1 && q==1) {nk=(now>>2)^q; insert(nk,ans[cur][k]);} 96 } 97 len[cur]=0; cur^=1; 98 } 99 100 int Ans=0; 101 for (int i=1;i<=len[cur];i++) if (state[cur][i]==0) {Ans=ans[cur][i]; break;} 102 printf("%d\n",Ans); 103 return 0; 104 }
View Code

BZOJ2331: [SCOI2011]地板