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