原题走这里
一看数据范围就知道是状压
首先预处理出s[i][j]即n个字符串的第i位与字母j的匹配状态
设d[i][S]为前i个字母匹配状态为S的情况下的方案
然后对于每个状态枚举下一位是多少就可以了
最后统计一波~~~AC
代码如下:
#include <bits/stdc++.h>
#define MOD 1000003
using namespace std;
int T,n,m,len,ret,S[60][26],d[2][1<<15];
char ch[16][60];
int main()
{
cin>>T;
while(T--)
{
ret=0;
memset(d,0,sizeof(d));
memset(S,0,sizeof(S));
cin>>n>>m;
for(int i=0;i<n;i++)
{
scanf("%s",ch[i]);
}
len=strlen(ch[0]);
if(m>n)
{
cout<<0<<endl;
continue;
}
for(int i=0;i<len;i++)
{
for(int j=0;j<26;j++)
{
for(int k=0;k<n;k++)
{
if(j+'a'==ch[k][i]||ch[k][i]=='?')S[i][j]^=(1<<k);
}
}
}
d[0][(1<<n)-1]=1;
for(int i=0,cur=0;i<len;i++,cur^=1)
{
memset(d[cur^1],0,sizeof(d[cur^1]));
for(int j=0;j<(1<<n);j++)
{
if(!d[cur][j])continue;
int temp=d[cur][j];
for(int c=0;c<26;c++)
{
(d[cur^1][j&S[i][c]]+=temp)%=MOD;
}
}
}
for(int i=0;i<(1<<n);i++)
{
int cnt=0;
for(int j=0;j<n;j++)
{
cnt+=(i>>j&1);
}
if(cnt==m)
{
(ret+=d[len&1][i])%=MOD;
}
}
cout<<ret<<endl;
}
}