完了……好像……已经把插头dp全都忘光了……
可以去看看这篇blog
为了卡常变得丧心病狂的代码
//minamoto
#include<bits/stdc++.h>
#define ll long long
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=25,P=23333,M=40005;
struct MAIN{
int n,m;char s[N];bool mp[N][N];
int cnt[2],cur,vis[2][M],hsh[P+5],ex,ey,S,l,r,dt,val;
ll dp[2][M],ans;
void insert(R int S,R ll sum){
R int pos=S%P;
while(hsh[pos]){
if(vis[cur][hsh[pos]]==S)return (void)(dp[cur][hsh[pos]]+=sum);
pos=(pos+1)%P;
}hsh[pos]=++cnt[cur],vis[cur][hsh[pos]]=S,dp[cur][hsh[pos]]=sum;
}
MAIN(){
scanf("%d%d",&n,&m);
fp(i,1,n){
scanf("%s",s+1);
fp(j,1,m)if(s[j]=='.')mp[i][j]=1,ex=i,ey=j;
}
dp[0][1]=cnt[0]=1;
fp(i,1,n){
fp(j,1,m){
cnt[cur^=1]=0;memset(hsh,0,sizeof(hsh));
fp(k,1,cnt[cur^1]){
S=vis[cur^1][k],l=(S>>((j-1)<<1))&3,r=(S>>(j<<1))&3;
if(!mp[i][j]){if(!l&&!r)insert(S,dp[cur^1][k]);continue;}
if(!l&&!r){
if(!mp[i][j+1]||!mp[i+1][j])continue;
insert(S^(1<<((j-1)<<1))^(2<<(j<<1)),dp[cur^1][k]);
}if(l&&!r){
if(mp[i][j+1])insert(S^(l<<((j-1)<<1))^(l<<(j<<1)),dp[cur^1][k]);
if(mp[i+1][j])insert(S,dp[cur^1][k]);
}if(!l&&r){
if(mp[i+1][j])insert(S^(r<<(j<<1))^(r<<((j-1)<<1)),dp[cur^1][k]);
if(mp[i][j+1])insert(S,dp[cur^1][k]);
}if(l==1&&r==1){
dt=1;
fp(p,j+1,m){
val=(S>>(p<<1))&3;
if(val==1)++dt;if(val==2)--dt;
if(!dt){S^=(2<<(p<<1))^(1<<(p<<1));break;}
}insert(S^(1<<((j-1)<<1))^(1<<(j<<1)),dp[cur^1][k]);
}if(l==2&&r==2){
dt=1;
fd(p,j-2,0){
val=(S>>(p<<1))&3;
if(val==1)--dt;if(val==2)++dt;
if(!dt){S^=(1<<(p<<1))^(2<<(p<<1));break;}
}insert(S^(2<<((j-1)<<1))^(2<<(j<<1)),dp[cur^1][k]);
}if(l==2&&r==1)insert(S^(2<<((j-1)<<1))^(1<<(j<<1)),dp[cur^1][k]);
if(l==1&&r==2&&i==ex&&j==ey)ans+=dp[cur^1][k];
}
}
fp(j,1,cnt[cur])vis[cur][j]<<=2;
}
printf("%lld
",ans);
}
}T;
int main(){return 0;}