壮哉我插头DP
jys
posted @ Jul 23, 2013 01:25:56 PM
in 未分类
, 1156 阅读
终于调出来了。
细节太多。。就算想清楚原理和实现细节实现出来还会有一千万个错。。
#include <cstdio> #include <iostream> #include <cstdlib> #include <queue> using namespace std; int map[12][12],n,m;//m列n行 char tmp[10];bool endofline; std::queue<int> q[2];bool flag[2][900]; int findr[10][900],findl[10][900]; int get(int num,int i){return num&(1<<i);} bool isleft(int num,int i){return get(num,2*i-2)>0;} bool isright(int num,int i){return get(num,2*i-1)>0;} bool isempty(int num,int i){return (!isleft(num,i))&&(!isright(num,i));} int index(int x,int y){return (x-1)*m+y;} int change(int num,int i,int v1,int v2) { if((v1==1)^(get(num,2*i-2)>0))num^=(1<<(2*i-2)); if((v2==1)^(get(num,2*i-1)>0))num^=(1<<(2*i-1)); return num; } int stk[11],pos[11],top; int zip[300000],unzip[900],tmpl[11],tmpr[11]; int f[2][900],ind; bool check(int state) { int i; for(i=1;i<m;i++)if(!isempty(state,i))return false; if(isleft(state,m)&&isright(state,m+1))return true; return false; } void updata(int from,int t) { if(endofline) { if(!isempty(unzip[t],m+1))return; int newstate=unzip[t]<<2; t=zip[newstate]; } f[1^ind][t]+=f[ind][from];if(!flag[1^ind][t]){q[1^ind].push(t);flag[1^ind][t]=true;} } void clear() { memset(f,0,sizeof(f)); memset(flag,0,sizeof(flag)); while(!q[0].empty())q[0].pop(); while(!q[1].empty())q[1].pop(); } void solve() { int i,j,cnt=0,state,newstate,ans=0;bool legal; for(j=0;j<(1<<(2*(m+1)));j++) { top=0;legal=true; for(i=1;i<=m+1;i++) { if(isleft(j,i)&&isright(j,i)){legal=false;break;} if(isleft(j,i)) { stk[++top]=1; pos[top]=i; } else if(isright(j,i)) { if(top==0||stk[top]==2){legal=false;break;} if(stk[top]==1) { tmpr[pos[top]]=i; tmpl[pos[top]]=0; tmpl[i]=pos[top]; tmpr[i]=0; top--; } } else tmpl[i]=tmpr[i]=0; } if(top>0)legal=false; if(legal) { ++cnt;unzip[cnt]=j;zip[j]=cnt; for(i=1;i<=m+1;i++){findl[i][cnt]=tmpl[i];findr[i][cnt]=tmpr[i];} } else zip[j]=0; } for(i=0;i<n;i++) { scanf("%s",tmp); for(j=0;j<m;j++) map[i+1][j+1]=(tmp[j]=='.'); } n++;map[n][1]=1;map[n][m]=1; for(i=2;i<m;i++)map[n][i]=0; n++;for(i=1;i<=m;i++)map[n][i]=1; q[1].push(1);f[1][1]=1; for(i=1;i<=n;i++)for(j=1;j<=m;j++) { ind=index(i,j)&1; memset(flag[ind^1],0,sizeof(flag[ind^1])); memset(f[ind^1],0,sizeof(f[ind^1])); endofline=(j==m); while(!q[ind].empty()) { state=q[ind].front();q[ind].pop(); state=unzip[state]; if(map[i][j]!=1) { if(isempty(state,j)&&isempty(state,j+1)) updata(zip[state],zip[state]); continue; } if(i==n&&j==m) { if(check(state))ans+=f[ind][zip[state]]; continue; } if(isempty(state,j)&&isempty(state,j+1)) { newstate=change(state,j,1,0); newstate=change(newstate,j+1,0,1); updata(zip[state],zip[newstate]); } //-# if(isright(state,j)&&isempty(state,j+1)) { updata(zip[state],zip[state]); newstate=change(state,j,0,0); newstate=change(newstate,j+1,0,1); updata(zip[state],zip[newstate]); } if(isleft(state,j)&&isempty(state,j+1)) { updata(zip[state],zip[state]); newstate=change(state,j,0,0); newstate=change(newstate,j+1,1,0); updata(zip[state],zip[newstate]); } //#- if(isempty(state,j)&&isleft(state,j+1)) { updata(zip[state],zip[state]); newstate=change(state,j,1,0); newstate=change(newstate,j+1,0,0); updata(zip[state],zip[newstate]); } if(isempty(state,j)&&isright(state,j+1)) { updata(zip[state],zip[state]); newstate=change(state,j,0,1); newstate=change(newstate,j+1,0,0); updata(zip[state],zip[newstate]); } //-- if(isright(state,j)&&isleft(state,j+1)) { newstate=change(state,j,0,0); newstate=change(newstate,j+1,0,0); updata(zip[state],zip[newstate]); } if(isleft(state,j)&&isleft(state,j+1)) { newstate=change(state,j,0,0); newstate=change(newstate,j+1,0,0); newstate=change(newstate,findr[j+1][zip[state]],1,0); updata(zip[state],zip[newstate]); } if(isright(state,j)&&isright(state,j+1)) { newstate=change(state,j,0,0); newstate=change(newstate,j+1,0,0); newstate=change(newstate,findl[j][zip[state]],0,1); updata(zip[state],zip[newstate]); } /* if(isleft(state,j)&&isright(state,j+1)) if(i==n&&j==m)ans+=f[ind][zip[state]]; */ } } printf("%d\n",ans); } int main() { while(scanf("%d %d",&n,&m)!=EOF) { if(n==0&&m==0)break; clear(); solve(); } }