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; }