标签:删除 insert head 更新 while thml html 移动 图片
给出$n\times m$ 的方格,有些格子不能铺线,其它格子必须铺,形成一个闭合回路。问有多少种铺法?
使用括号表示法记录状态,记1为 ‘(‘ ,2为 ‘)‘ ,0为无插头,分8种情况讨论:
优化:使用链表存储状态为模数同余系的状态;滚动数组
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,m,map[15][15],endx,endy,bits[15],pre=1,cur,tots[2],state[2][600000],head[600000],tot; const int mod=590027; long long ans,dp[2][600000]; struct Edge { int to,nxt; }edge[600000]; inline int read() { int f=1,w=0; char ch=0; while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) f=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { w=(w<<1)+(w<<3)+ch-‘0‘; ch=getchar(); } return f*w; } void insert(int sta,long long val) { int key=sta%mod; for(int i=head[key];i;i=edge[i].nxt) { if(state[cur][edge[i].to]==sta) { dp[cur][edge[i].to]+=val; return; } } tots[cur]++; state[cur][tots[cur]]=sta; dp[cur][tots[cur]]=val; edge[++tot]=(Edge){tots[cur],head[key]}; head[key]=tot; } void DP() { tots[cur]=1; state[cur][1]=0; dp[cur][1]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=tots[cur];j++) { state[cur][j]<<=2; } for(int j=1;j<=m;j++) { tot=0; memset(head,0,sizeof(head)); swap(cur,pre); tots[cur]=0; int nowsta=0,d=0,r=0; long long nowans=0; for(int k=1;k<=tots[pre];k++) { nowsta=state[pre][k]; nowans=dp[pre][k]; d=(nowsta>>bits[j])%4; r=(nowsta>>bits[j-1])%4; if(!map[i][j]) { if(!d&&!r) { insert(nowsta,nowans); } } else if(!d&&!r) { if(map[i+1][j]&&map[i][j+1]) { insert(nowsta+(1<<bits[j-1])+2*(1<<bits[j]),nowans); } } else if(!d&&r) { if(map[i+1][j]) { insert(nowsta,nowans); } if(map[i][j+1]) { insert(nowsta-r*(1<<bits[j-1])+r*(1<<bits[j]),nowans); } } else if(!r&&d) { if(map[i][j+1]) { insert(nowsta,nowans); } if(map[i+1][j]) { insert(nowsta-d*(1<<bits[j])+d*(1<<bits[j-1]),nowans); } } else if(r==1&&d==1) { int cnt=1; for(int l=j+1;l<=m;l++) { if((nowsta>>bits[l])%4==1) { cnt++; } else if((nowsta>>bits[l])%4==2) { cnt--; } if(!cnt) { insert(nowsta-(1<<bits[j-1])-(1<<bits[j])-(1<<bits[l]),nowans); break; } } } else if(r==2&&d==2) { int cnt=1; for(int l=j-2;l>=0;l--) { if((nowsta>>bits[l])%4==1) { cnt--; } else if((nowsta>>bits[l])%4==2) { cnt++; } if(!cnt) { insert(nowsta-2*(1<<bits[j-1])-2*(1<<bits[j])+(1<<bits[l]),nowans); break; } } } else if(r==2&&d==1) { insert(nowsta-2*(1<<bits[j-1])-(1<<bits[j]),nowans); } else { if(i==endx&&j==endy) { ans+=nowans; } } } } } } int main() { n=read(); m=read(); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { char ch=0; while(ch!=‘.‘&&ch!=‘*‘) { ch=getchar(); } if(ch==‘.‘) { map[i][j]=1; endx=i; endy=j; } } } for(int i=1;i<=14;i++) { bits[i]=i<<1; } DP(); printf("%lld\n",ans); return 0; }
标签:删除 insert head 更新 while thml html 移动 图片
原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13398081.html