Bzoj1879 [Sdoi2009]Bill的挑战

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 724  Solved: 363

Description

Input

本题包含多组数据。 第一行:一个整数T,表示数据的个数。 对于每组数据: 第一行:两个整数,N和K(含义如题目表述)。 接下来N行:每行一个字符串。

Output

1
2 1
a?
?b

Sample Input

50

Sample Output

对于30%的数据,T ≤ 5,N ≤ 5,字符串长度≤ 20;
对于70%的数据,T ≤ 5,N ≤ 13,字符串长度≤ 30;
对于100%的数据,T ≤ 5,N ≤ 15,字符串长度≤ 50。

HINT

 

Source

动规 状压DP

这题简直思路清奇。

刚开始想的是预处理出每两个串之间能否匹配,以及每个串能匹配它之前出现的多少串,然后DP。←想来好复杂,而且可能还要容斥,那就是超复杂了。

  (说不定也能强行做出来呢 http://www.cnblogs.com/SilverNebula/p/6001294.html)

再一看数据范围,啊,状压你好。

所有串的长度一样,所以可以统一处理,预处理g[i][j]=x表示字符j可以和x集合内的串的第i位匹配

f[匹配长度][集合]=方案数

f[0][全满集合]=1

f[i][ k&g[i-1][j] ]+=f[递推位数i-1][枚举集合k]

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 const int mod=1e6+3;
10 const int mxn=100010;
11 int f[51][1<<15];
12 int g[51][27];
13 char s[16][52];
14 int T,n,K;
15 int main(){
16     int i,j;
17     scanf("%d",&T);
18     while(T--){
19         memset(f,0,sizeof f);
20         scanf("%d%d",&n,&K);
21         for(i=0;i<n;i++){scanf("%s",s[i]);}
22         int len=strlen(s[0]);
23         for(i=0;i<len;i++)//长度 
24             for(int k=0;k<26;k++){//字母     
25                 g[i][k]=0;
26                 for(j=0;j<n;j++){//
27                     if(s[j][i]=='?' || s[j][i]==k+'a')g[i][k]|=(1<<j);
28                 }
29             }
30         int ed=(1<<n)-1;
31         f[0][ed]=1;
32         for(i=1;i<=len;i++){
33             for(int k=0;k<=ed;k++){
34                 if(f[i-1][k])
35                 for(j=0;j<26;j++){
36                     (f[i][k&g[i-1][j]]+=f[i-1][k])%=mod;
37                 }
38             }
39         }
40         int ans=0;
41         for(int k=0;k<=ed;k++){
42             int tmp=k,cnt=0;
43             while(tmp){
44                 cnt++;
45                 tmp-=tmp&-tmp;
46             }
47             if(cnt==K)ans=(ans+f[len][k])%mod;
48         }
49         printf("%d
",ans);
50     }
51     return 0;
52 }
本文为博主原创文章,转载请注明出处。
原文地址:https://www.cnblogs.com/SilverNebula/p/6482928.html