input | output |
---|---|
4 4 **.. .... .... .... |
2 |
4 4 .... .... .... .... |
6 |
插头dp
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int bi=1e8; int i; struct na{ int x,z; na(int xx,int zz):x(xx),z(zz){} }; struct big{ int a[4]; big(){ memset(a,0,sizeof(a)); a[0]=1; } big operator =(int x){ if (x==0){ memset(a,0,sizeof(a)); a[0]=1; return *this; } a[0]=0; while (x){ a[0]++; a[a[0]]=x%bi; x/=bi; } if (!a[0]) a[0]=1; return *this; } big operator +(const big &x){ big r; if (a[0]<x.a[0]) r.a[0]=x.a[0];else r.a[0]=a[0]; for (i=1;i<=r.a[0];i++) r.a[i]=a[i]+x.a[i]; for (i=1;i<=r.a[0];i++) if (r.a[i]>=bi){ r.a[i]-=bi;r.a[i+1]++; if (i==r.a[0]) r.a[0]++; } return r; } }ans; int n,m,x,y,z,a[21],k,p1,p2,end; bool map[21][21]; big f[2][1594324]; int v[2][1594324]; queue <na> q; inline int gx(int x,int q1,int q2){k=0;for (register int i=m+1;i;i--) k=k*3+(i==x?q1:(i==x+1?q2:a[i]));return k;} inline void up(int x,int z,big lj){ x++; k=x%2; if (v[k][z]!=x) v[k][z]=x,f[k][z]=0,q.push(na(x,z)); f[k][z]=f[k][z]+lj; } char c[10]; int main(){ register int i,j; scanf("%d%d",&n,&m); for (j=1;j<=n;j++){ scanf("%s",c); for (i=1;i<=m;i++) map[i][j]=c[i-1]=='.'; } end=n*m-1; while(!map[end%m+1][end/m+1]) end--; f[0][0]=v[0][0]=1; q.push(na(0,0)); while(!q.empty()){ na no=q.front();q.pop(); big an=f[no.x%2][no.z]; if(no.x%m==0) no.z*=3; x=no.x%m+1;y=no.x/m+1; for (i=1;i<=m+1;i++) a[i]=0; for (i=1,j=no.z;j;i++,j/=3) a[i]=j%3; if (!map[x][y])up(no.x,gx(x,0,0),an);else if (a[x]==1&&a[x+1]==2){ if (no.x==end) ans=ans+an; }else if (a[x]==2&&a[x+1]==1) up(no.x,gx(x,0,0),an);else if (a[x]==0&&a[x+1]==0){ if (map[x][y+1]&&map[x+1][y]) up(no.x,gx(x,1,2),an); }else if (a[x]==0){ if (map[x+1][y]) up(no.x,gx(x,0,a[x+1]),an); if (map[x][y+1]) up(no.x,gx(x,a[x+1],0),an); }else if (a[x+1]==0){ if (map[x+1][y]) up(no.x,gx(x,0,a[x]),an); if (map[x][y+1]) up(no.x,gx(x,a[x],0),an); }else if (a[x]==a[x+1]){ p1=p2=0; if (a[x]==1) for (j=0,i=x+2;i<=m;i++){ if (a[i]==1) j--; if (a[i]==2) j++; if (j>0&&!p1) p1=i,j--; if (j>0&&p1){p2=i;break;} }else for (j=0,i=x-1;i;i--){ if (a[i]==1) j++; if (a[i]==2) j--; if (j>0&&!p2) p2=i,j--; if (j>0&&p2){p1=i;break;} } a[p1]=1;a[p2]=2;up(no.x,gx(x,0,0),an); } } printf("%d",ans.a[ans.a[0]]); for (i=ans.a[0]-1;i;i--) printf("%08d",ans.a[i]); }