Circuits
Time Limit: 30000/15000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 381 accepted submission (s): 128
Problem description given a map of N * m (2 <= n, m <= 12 ),'. 'Means empty, '*' means Wils. you need to build K circuits and no circuits cocould be nested in another. A circuit is a route connecting adjacent cells in a cell sequence, and also connect the first cell and
Last cell. Each cell shocould be exactly in one circuit. How many ways do we have?
Input the first line of input has an integer T, number of cases.
For each case:
The first line has three integers n m K, as described above.
Then the following n lines each has m characters, '.' or '*'.
Output for each case output one lines.
Each line is the answer % 1000000007 to the case.
Sample Input
24 4 1**..............4 4 1................
Sample output
26
Source2012 ACM/ICPC Asia Regional Tianjin online
Recommendliuyiding question: http://acm.hdu.edu.cn/showproblem.php? PID = 4285 question: I want to give you a square matrix. Some parts can pass through, but some parts cannot. It is required to cover all the grids that can pass through the square matrix, these circuits cannot contain each other... Analysis: This is the problem of multiple circuits in the plug DP. However, the difficulty of this problem is that the circuits cannot be included in each other. I have been thinking about this for a long time. I did not expect a good method, think of increasing the number of plug... It is too complicated. The Internet says that if the current merge is possible, the number of parentheses containing this loop must be an even number. This is easy to understand. If it is an odd number, no matter how you do it, the loop cannot be contained... In addition, some people say that the memory will use map... When I used it, the memory burst. If I didn't use it, I went through = and the speed was still relatively fast. I flushed it to the top 10 with the ^_^ code:
#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int mm=100007;const int mod=1000000007;typedef long long LL;struct hashTable{ int h[mm],s[mm],p[mm],t; LL v[mm][37]; void push(int w,int j,LL val) { int i,id=w%mm; for(i=h[id];i>=0;i=p[i]) if(s[i]==w) { v[i][j]+=val; if(v[i][j]>=mod)v[i][j]=v[i][j]%mod; return; } v[t][j]=val,s[t]=w,p[t]=h[id],h[id]=t++; } void clear() { while(t--)memset(v[t],0,sizeof(v[t])); t=0,memset(h,-1,sizeof(h)); }}f[2];int i,j,k,g1,g2,n,m,K,t;bool g[22][22];char c;bool ok(int s){ if(s==1)return g[i+1][j]; if(s==2)return g[i][j+1]; return g[i+1][j]&&g[i][j+1];}bool can(int s){ int sum=0,r=j; while(r--) { if((s&3)==1)++sum; if((s&3)==2)--sum; s>>=2; } return (sum&1)==0;}int Link(int s,int flag){ int w,n=1,x=3<<(j<<1),a=(2-flag)<<(j<<1); while(n) { if(flag)x<<=2,a<<=2; else x>>=2,a>>=2; w=s&x; if(w)n+=(w==a)?1:-1; } return s^x;}void Work(int s,int k,LL val){ int e,w=j<<1,x=(s>>w)&15; if(x==9) { if(k<K&&can(s))f[g2].push(s^(9<<w),k+1,val); } else if(!x) { if(ok(3))f[g2].push(s^(9<<w),k,val); } else if(!(x&3)||!(x&12)) { if(x&3)e=0,x|=x<<2; else e=1,x|=x>>2; if(ok(1+e))f[g2].push(s,k,val); if(ok(1+!e))f[g2].push(s^(x<<w),k,val); } else if(x==6)f[g2].push(s^(x<<w),k,val); else f[g2].push(Link(s^(x<<w),x==5),k,val);}LL PlugDP(){ if(K>n*m/4)return 0; f[0].clear(); f[0].push(0,0,1); for(g2=i=0;i<n;++i) { for(k=0;k<f[g2].t;++k)f[g2].s[k]<<=2; for(j=0;j<m;++j) if(g[i][j])for(g1=g2,g2=!g2,f[g2].clear(),k=0;k<f[g1].t;++k) for(int s=0;s<K;++s) if(f[g1].v[k][s])Work(f[g1].s[k],s,f[g1].v[k][s]); } LL ret=0; for(k=0;k<f[g2].t;++k) if(!f[g2].s[k])ret+=f[g2].v[k][K]; return ret;}int main(){ scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&K); memset(g,0,sizeof(g)); for(i=0;i<n;++i) for(j=0;j<m;++j) scanf(" %c",&c),g[i][j]=(c=='.'); printf("%I64d\n",PlugDP()); } return 0;}