poj1739 Tony's Tour 插头dp求哈密顿回路
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 10 #define M (1<<18)+2 int n,m; int a[N][N]; int bb[N]; struct hash{ int id[M],val[M],st[M]; int cnt; void clear(){ for(int i=1;i<=cnt;i++)id[st[i]]=0; cnt=0; } void push(int x,int y){ if(!id[x]){ id[x]=++cnt; val[cnt]=y; st[cnt]=x;}else{ val[id[x]]+=y; } } int cha(int x){ if(!id[x])return -1; return val[id[x]]; } }T[2]; int gai(int x,int y,int z){ return ((x&(~(1<<(2*y-2))))&(~(1<<(2*y-1))))+z*(1<<y*2-2); } void out(int x){ for(int k=1;k<=m+1;k++){ cout<<((x>>((k-1)*2))&3); } cout<<" "; } int main(){ // freopen("1.in","r",stdin); //freopen("2.out","w",stdout); while(1){ scanf("%d%d",&n,&m); if(n==0&&m==0)break; memset(a,0,sizeof(a)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ char b; scanf(" %c",&b); if(b=='#'){ a[i][j]=1; } } } T[0].clear(); T[1].clear(); T[0].push(0,1); int h=-1; for(int i=1;i<=n;i++){ //cout<<endl; for(int j=1;j<=m;j++){ h++; int u=h&1; int w=u^1; int vv=0; T[w].clear(); for(int z=1;z<=T[u].cnt;z++){ int now=T[u].st[z]; vv=T[u].cha(now); if(j==1){ if(now>>m*2){ continue; }else{ now=gai(now,m+1,0)<<2; } } for(int k=1;k<=m+1;k++){ bb[k]=(now>>((k-1)*2))&3; } if(a[i][j]){ if(bb[j]||bb[j+1]){ continue; }else{ T[w].push(now,vv); continue; } } int now2=gai(gai(now,j,0),j+1,0); if(bb[j]==0){ if(bb[j+1]==0){ T[w].push(now2+((1+2*4)<<(j*2-2)),vv); } if(bb[j+1]==1){ T[w].push(now2+(1<<(j*2-2)),vv); T[w].push(now2+((1*4)<<(j*2-2)),vv); } if(bb[j+1]==2){ T[w].push(now2+((2)<<(j*2-2)),vv); T[w].push(now2+((2*4)<<(j*2-2)),vv); } } if(bb[j]==1){ if(bb[j+1]==0){ T[w].push(now2+((1)<<(j*2-2)),vv); T[w].push(now2+((1*4)<<(j*2-2)),vv); } if(bb[j+1]==1){ int tot=0; for(int k=j+2;k<=m;k++){ if(bb[k]==2)tot--; if(bb[k]==1)tot++; if(tot==-1){ T[w].push(gai(now2,k,1),vv);break; } } } /*if(bb[j+1]==2){ T[w].push(now2,vv); }*/ } if(bb[j]==2){ if(bb[j+1]==0){ T[w].push(gai(now2,j,2),vv); T[w].push(gai(now2,j+1,2),vv); } if(bb[j+1]==1){ T[w].push(now2,vv); } if(bb[j+1]==2){ int tot=0; for(int k=j-1;k>=1;k--){ if(bb[k]==2)tot--; if(bb[k]==1)tot++; if(tot==1){ T[w].push(gai(now2,k,2),vv); break; } } } } } } } int hh=T[(h&1)^1].cha(1+(2<<(2*(m-1)))); if(hh==-1)hh=0; printf("%d\n",hh); } }