依然是经典的棋盘模型,和原题差不多。
但是由于题目有限定回路数,要在状态中加一维表示已形成的回路数。
此外,由于不允许回路嵌套,我们要有一个特殊规定:
如果当前的一对插头要形成一个回路(也就是()到##的转移),当前这对括号前面的插头数必须为偶数,否则会出现嵌套。
大致证明不太明白,不过可以感性理解一下:
如果是本对括号被偶数层括号套着,比如连通性为(123321)的情况,由于2外面只有1包着,所以只能转移到1221或者1133,1221又只能转移为11等等。于是……就这样了
代码如下:
#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
int T,n,m,q,H[42000],s,d[2][42000][37];
map<int,int> IH;
char ch[15][15];
void getHash(int k,int x,int y)
{
if(y<0||y>m-k+1)return;
if(k==m+1)IH[x]=s,H[s++]=x;
getHash(k+1,x<<2,y);
getHash(k+1,x<<2|2,y-1);
getHash(k+1,x<<2|3,y+1);
}
int dp()
{
d[1][0][0]=1;
for(int i=1,cur=1;i<=n;i++,cur^=1)
{
for(int j=0;j<m;j++,cur^=1)
{
memset(d[cur^1],0,sizeof(d[cur^1]));
if(ch[i][j]=='.')
{
for(int k=0;k<s;k++)
{
int t=H[k],x=t>>(j<<1)&3,y=t>>((j+1)<<1)&3;
for(int l=0;l<q;l++)
{
int temp=d[cur][k][l];
if(!temp)continue;
if(x+y==2||x+y==3)
{
(d[cur^1][k][l]+=temp)%=MOD;
(d[cur^1][IH[t^((x|y)<<(j<<1))^((x|y)<<((j+1)<<1))]][l]+=temp)%=MOD;
}
if(x==0&&y==0)
{
(d[cur^1][IH[t^(14<<(j<<1))]][l]+=temp)%=MOD;
}
if(x==2&&y==3)
{
int jj=0;
for(int ii=j-1;ii>=0;ii--)
{
if((t>>(ii<<1)&3)==2)jj++;
if((t>>(ii<<1)&3)==3)jj--;
}
if(jj%2==0)(d[cur^1][IH[t^(14<<(j<<1))]][l+1]+=temp)%=MOD;
}
if(x==3&&y==2)
{
(d[cur^1][IH[t^(11<<(j<<1))]][l]+=temp)%=MOD;
}
if(x==2&&y==2)
{
for(int ii=j+2,jj=0;ii<=m;ii++)
{
if((t>>(ii<<1)&3)==2)jj++;
if((t>>(ii<<1)&3)==3)jj--;
if(jj<0)
{
(d[cur^1][IH[t^(1<<(ii<<1))^(10<<(j<<1))]][l]+=temp)%=MOD;
break;
}
}
}
if(x==3&&y==3)
{
for(int ii=j-1,jj=0;ii;ii--)
{
if((t>>(ii<<1)&3)==2)jj++;
if((t>>(ii<<1)&3)==3)jj--;
if(jj>0)
{
(d[cur^1][IH[t^(1<<(ii<<1))^(15<<(j<<1))]][l]+=temp)%=MOD;
break;
}
}
}
}
}
}
else
{
for(int k=0;k<s;k++)
{
int t=H[k],x=t>>(j<<1)&3,y=t>>((j+1)<<1)&3;
if(x==0&&y==0)
{
memcpy(d[cur^1][k],d[cur][k],sizeof(d[cur][k]));
}
}
}
}
memset(d[cur^1],0,sizeof(d[cur^1]));
for(int j=0;H[j]<(1<<(m<<1));j++)
{
memcpy(d[cur^1][IH[H[j]<<2]],d[cur][j],sizeof(d[cur][j]));
}
}
return d[n*(m+1)&1][0][q];
}
int main()
{
cin>>T;
while(T--)
{
IH.clear();
memset(H,0,sizeof(H));
memset(d,0,sizeof(d));
s=0;
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
cin>>ch[i];
}
getHash(0,0,0);
cout<<dp()<<endl;
}
}