题目大意:给定一张有坏点的地图,要求用L型地毯将整个图覆盖,求方案数
插头DP。。。
首先由于R*C<=100,故min(R,C)<=10
然后插头状态为:0-无插头 1-有一个没有拐过的插头 2-有一个拐过的插头
然后就自己YY吧。。。。
珍爱生命,远离memset
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 110 #define MOD 20110520 using namespace std; int m,n; char s[M][M]; int sta[200200],tot; bool Available(int temp) { int i; for(i=1;i<=n+1;i++) { if( (temp&3)==3 ) return false; temp>>=2; } return true; } struct Hash_Table{ struct List{ int hash,val; List *next; List(int _,List *__): hash(_),val(0),next(__) {} }*head[200199]; int& operator [] (int x) { int pos=x%200199; List *temp; for(temp=head[pos];temp;temp=temp->next) if(temp->hash==x) return temp->val; return (head[pos]=new List(x,head[pos]))->val; } bool Find(int x) { int pos=x%200199; List *temp; for(temp=head[pos];temp;temp=temp->next) if(temp->hash==x) return true; return false; } }f,g; int main() { int i,j,k; cin>>m>>n; for(i=1;i<=m;i++) scanf("%s",s[i]+1); if(m<n) { swap(m,n); static char temp[M][M]; for(i=1;i<=m;i++) for(j=1;j<=n;j++) temp[i][j]=s[j][i]; memcpy(s,temp,sizeof s); } for(i=0;i<1<<(n+1)*2;i++) if(Available(i)) sta[++tot]=i; f[0]=1; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { memset(&g,0,sizeof g); for(k=1;k<=tot;k++) { int sta=::sta[k]; if(!f.Find(sta)) continue; if(s[i][j]=='*') { if( ((sta>>(n-j)*2)&15)==0 ) (g[sta]+=f[sta])%=MOD; } else { switch( (sta>>(n-j)*2)&15 ) { case 0: (g[sta^(0<<(n-j)*2)^(1<<(n-j)*2)]+=f[sta])%=MOD; (g[sta^(0<<(n-j)*2)^(4<<(n-j)*2)]+=f[sta])%=MOD; (g[sta^(0<<(n-j)*2)^(10<<(n-j)*2)]+=f[sta])%=MOD; break; case 1: (g[sta^(1<<(n-j)*2)^(4<<(n-j)*2)]+=f[sta])%=MOD; (g[sta^(1<<(n-j)*2)^(2<<(n-j)*2)]+=f[sta])%=MOD; break; case 2: (g[sta^(2<<(n-j)*2)^(8<<(n-j)*2)]+=f[sta])%=MOD; (g[sta^(2<<(n-j)*2)^(0<<(n-j)*2)]+=f[sta])%=MOD; break; case 4: (g[sta^(4<<(n-j)*2)^(8<<(n-j)*2)]+=f[sta])%=MOD; (g[sta^(4<<(n-j)*2)^(1<<(n-j)*2)]+=f[sta])%=MOD; break; case 5: (g[sta^(5<<(n-j)*2)^(0<<(n-j)*2)]+=f[sta])%=MOD; break; case 8: (g[sta^(8<<(n-j)*2)^(0<<(n-j)*2)]+=f[sta])%=MOD; (g[sta^(8<<(n-j)*2)^(2<<(n-j)*2)]+=f[sta])%=MOD; break; } } } memcpy(&f,&g,sizeof f); } memset(&g,0,sizeof g); for(k=1;k<=tot;k++) { int sta=::sta[k]; if(!f.Find(sta)) continue; if( (sta&3)==0 ) g[sta>>2]=f[sta]; } memcpy(&f,&g,sizeof f); } cout<<f[0]<<endl; }
原文地址:http://blog.csdn.net/popoqqq/article/details/44937751