BZOJ 2331 SCOI2011 地板 插头DP

来源:互联网 发布:苹果手机上的编程软件 编辑:程序博客网 时间:2024/04/28 04:51

题目大意:给定一张有坏点的地图,要求用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 20110520using 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;}


0 0