[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 }

 

转载于:https://www.cnblogs.com/Yuzao/p/7227664.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值