| input | output |
|---|---|
4 4 **.. .... .... .... |
2 |
4 4 .... .... .... .... |
6 |
插头dp模板题。
非常好的文章。
我代码的处理顺序是:
1.##-->()
2.#(-->#( 或 )# #)-->#) 或 )#
3.(#-->(# 或 #( )#-->)# 或 #)
4.((-->##
5.))-->##
6.()-->##
7.)(-->##
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#define LL long long
#define M 300000+5
using namespace std;
char s[20];
int tot,a[15][15],n,m,total[2],now,pre,ex,ey,bit[20];
int h[M];
struct edge
{
int y,ne;
}e[M];
LL f[2][M],state[2][M],ans=0;
void Solve(LL s,LL num)
{
int pos=s%(M-5);
for (int i=h[pos];i;i=e[i].ne)
if (state[now][e[i].y]==s)
{
f[now][e[i].y]+=num;
return;
}
total[now]++;
state[now][total[now]]=s;
f[now][total[now]]=num;
e[++tot].y=total[now];
e[tot].ne=h[pos];
h[pos]=tot;
}
void Plugdp()
{
now=0;
total[now]=1;
state[now][1]=0;
f[now][1]=1;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=total[now];j++)
state[now][j]<<=2;
for (int j=1;j<=m;j++)
{
tot=0;
memset(h,0,sizeof(h));
pre=now,now=pre^1;
total[now]=0;
for (int k=1;k<=total[pre];k++)
{
LL s=state[pre][k];
LL num=f[pre][k];
int p=(s>>bit[j-1])%4,q=(s>>bit[j])%4;
if (!a[i][j])
{
if (p+q==0)
Solve(s,num);
}
else if (p+q==0)
{
if (!a[i][j+1]||!a[i+1][j])
continue;
s=s+(1<<bit[j-1])+2*(1<<bit[j]);
Solve(s,num);
}
else if (!p&&q)
{
if (a[i][j+1])
Solve(s,num);
if (a[i+1][j])
s=s-q*(1<<bit[j])+q*(1<<bit[j-1]),
Solve(s,num);
}
else if (p&&!q)
{
if (a[i+1][j])
Solve(s,num);
if (a[i][j+1])
s=s-p*(1<<bit[j-1])+p*(1<<bit[j]),
Solve(s,num);
}
else if (p+q==2)
{
int b=1;
for (int t=j+1;t<=m;t++)
{
int v=(s>>bit[t])%4;
if (v==1) b++;
if (v==2) b--;
if (!b)
{
s=s-(1<<bit[t]);
break;
}
}
s=s-(1<<bit[j-1])-(1<<bit[j]);
Solve(s,num);
}
else if (p+q==4)
{
int b=-1;
for (int t=j-2;t>=0;t--)
{
int v=(s>>bit[t])%4;
if (v==1) b++;
if (v==2) b--;
if (!b)
{
s=s+(1<<bit[t]);
break;
}
}
s=s-2*(1<<bit[j-1])-2*(1<<bit[j]);
Solve(s,num);
}
else if (p==1&&q==2)
{
if (i==ex&&j==ey)
ans+=num;
}
else if (p==2&&q==1)
{
s=s-2*(1<<bit[j-1])-(1<<bit[j]);
Solve(s,num);
}
}
}
}
}
int main()
{
for (int i=0;i<15;i++)
bit[i]=i<<1;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=m;j++)
{
a[i][j]=s[j]=='.';
if (s[j]=='.') ex=i,ey=j;
}
}
Plugdp();
printf("%lld\n",ans);
return 0;
}
原文:http://blog.csdn.net/regina8023/article/details/44837541