动态规划。
f[i][j]表示匹配了前i个字符,匹配的是j中的那些字符串(用二进制压缩)。
动规方程:f[i][j]=sum{f[i-1][j’]}。
边界:f[0][j]=1(j表示的是都被匹配的状态),f[0][j]=0(j表示的是没有都被匹配的状态)。
CODE:
/*
AUTHOR: Su Jiao
DATE: 2010-7-26
DESCRIPTION:
山东2009年省选 Bill的挑战
*/
#include <stdio.h>
#include <string.h>
const int MAXLENGTH=50;
const int MAXN=15;
const int MODER=1000003;
const int MAXALPHABET=128;
typedef char string[MAXLENGTH+1];
int T,N,K;
string s[MAXN];
int f[MAXLENGTH+1][1<<MAXN];
int m[MAXLENGTH][MAXALPHABET];
int NN;
int length;
int main()
{
scanf(“%d”,&T);
for (int t=0;t<T;t++)
{
scanf(“%d%d”,&N,&K);
for (int i=0;i<N;i++) scanf(“%s”,&s[i]);
NN=1<<N;
length=strlen(s[0]);
memset(f,0,sizeof(f));
f[0][NN-1]=1;
for (int i=0;i<length;i++)
for (char match=’a’;match<=’z’;match++)
{
m[i][match]=0;
for (int k=0,kk=1;k<N;k++,kk<<=1)
if (s[k][i]==’?’||s[k][i]==match)
m[i][match]|=kk;
}
for (int i=0;i<length;i++)
for (int j=0;j<NN;j++)
if (f[i][j])
for (char match=’a’;match<=’z’;match++)
f[i+1][j&m[i][match]]=(f[i+1][j&m[i][match]]+f[i][j])%MODER;
int answer=0;
for (int i=0;i<NN;i++)
{
int c=0;
for (int j=1;j<NN;j<<=1)
if (i&j) c++;
if (c==K) answer=(answer+f[length][i])%MODER;
}
printf(“%d\n”,answer);
}
}