[SDOI2009]Bill的挑战

题目描述

 

题解:

因为要求的T长度一定,可定义f[i][j] 为前i位状态为j的方案,can[i][j]表示第i为字母j,可行的状态 每次往后推就行了

 

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 const int N=55,mod=1000003;
 9 int f[N][1<<15],can[55][55];char s[105][105];
10 int count(int x){
11     int cnt=0;
12     while(x)x-=(x&(-x)),cnt++;
13     return cnt;
14 }
15 void work(){
16     int n,least,l,tot;
17     memset(can,0,sizeof(can));
18     memset(f,0,sizeof(f));
19     scanf("%d%d",&n,&least);
20     tot=(1<<n)-1;
21     for(int i=1;i<=n;i++)
22         scanf("%s",s[i]+1);
23     l=strlen(s[1]+1);
24     for(int i=1;i<=l;i++)
25         for(int j=0;j<=25;j++)
26             for(int k=1;k<=n;k++)
27                 if(s[k][i]=='?' || s[k][i]==j+'a')
28                    can[i][j]+=(1<<(k-1));
29     f[0][tot]=1;
30     for(int i=0;i<l;i++){
31         for(int j=0;j<=tot;j++){
32             if(!f[i][j])continue;
33             for(int k=0;k<=25;k++){
34                 f[i+1][can[i+1][k]&j]+=f[i][j];
35                 f[i+1][can[i+1][k]&j]%=mod;
36             }
37         }
38     }
39     long long ans=0;
40     for(int i=0;i<=tot;i++){
41         if(count(i)==least)ans+=f[l][i],ans%=mod;
42     }
43     printf("%lld\n",ans);
44 }
45 int main()
46 {
47     int T;scanf("%d",&T);
48     while(T--)work();
49     return 0;
50 }

 

posted @ 2017-07-24 10:37  PIPIBoss  阅读(216)  评论(0编辑  收藏  举报