插头dp
f[i][j][S]表示转移到第i行第j列轮廓线为S的方案数
0表示没有插头,1表示插头没有拐过弯,2表示插头拐过弯
1、
3进制不好写,写4进制
一共3^11个状态,200000左右
bit[i]=i*2
取出4进制的第i位 (S/(1<<bit[i-1]))%4
状态的第j位 1<<bit[j-1]
2、
bfs只记录有用的状态
3、
因为f[i][j]只与f[i][j-1]有关,所以不妨用滚动数组
4、
f[i][j][S]表示转移到第i行第j列轮廓线为S的方案数
0表示没有插头,1表示插头没有拐过弯,2表示插头拐过弯
1、
3进制不好写,写4进制
一共3^11个状态,200000左右
bit[i]=i*2
取出4进制的第i位 (S/(1<<bit[i-1]))%4
状态的第j位 1<<bit[j-1]
2、
bfs只记录有用的状态
3、
因为f[i][j]只与f[i][j-1]有关,所以不妨用滚动数组
4、
有下插头的位置正下方必然有上插头
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define maxn 200010
#define mod 20110520
using namespace std;
int a[110][110];
int f[2][maxn],tot[2],hash[2][maxn],head[50010],to[maxn],next[maxn],bit[110];
int n,m,now,pre,num;
char s[110];
void add(int s,int d)
{
int x=s%50000;
for (int p=head[x];p;p=next[p])
if (hash[now][to[p]]==s)
{
f[now][to[p]]=(f[now][to[p]]+d)%mod;
return;
}
tot[now]++;
hash[now][tot[now]]=s;
f[now][tot[now]]=d;
num++;to[num]=tot[now];next[num]=head[x];head[x]=num;
}
void dp()
{
now=1;pre=0;
tot[now]=1;
hash[now][1]=0;
f[now][1]=1;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=tot[now];j++) hash[now][j]<<=2;
for (int j=1;j<=m;j++)
{
swap(now,pre);
tot[now]=0;
num=0;
memset(f[now],0,sizeof(f[now]));
memset(head,0,sizeof(head));
for (int k=1;k<=tot[pre];k++)
{
int s=hash[pre][k],num=f[pre][k];
if (!num) continue;
int p=(s/(1<<bit[j-1]))%4,q=(s/(1<<bit[j]))%4;
if (!a[i][j])
{
if (!p && !q) add(s,num);
}
else if (!p && !q)
{
if (a[i+1][j]) add(s+(1<<bit[j-1]),num);
if (a[i][j+1]) add(s+(1<<bit[j]),num);
if (a[i+1][j] && a[i][j+1]) add(s+(1<<bit[j-1]+1)+(1<<(bit[j]+1)),num);
}
else if (!p)
{
if (q==1)
{
s-=(1<<bit[j]);
if (a[i][j+1]) add(s+(1<<bit[j]+1),num);
if (a[i+1][j]) add(s+(1<<bit[j-1]),num);
}
else
{
s-=(1<<bit[j]+1);
add(s,num);
if (a[i+1][j]) add(s+(1<<bit[j-1]+1),num);
}
}
else if (!q)
{
if (p==1)
{
s-=(1<<bit[j-1]);
if (a[i][j+1]) add(s+(1<<bit[j]),num);
if (a[i+1][j]) add(s+(1<<bit[j-1]+1),num);
}
else
{
s-=(1<<bit[j-1]+1);
add(s,num);
if (a[i][j+1]) add(s+(1<<bit[j]+1),num);
}
}
else if (p==1 && q==1)
{
s-=(1<<bit[j-1])+(1<<bit[j]);
add(s,num);
}
}
}
}
}
int main()
{
for (int i=0;i<=100;i++) bit[i]=i*2;
scanf("%d%d",&n,&m);
if (n>=m)
{
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=m;j++)
if (s[j]=='_') a[i][j]=1; else a[i][j]=0;
}
}
else
{
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=m;j++)
if (s[j]=='_') a[j][i]=1; else a[j][i]=0;
}
swap(n,m);
}
dp();
printf("%d\n",f[now][1]);
return 0;
}