zoukankan      html  css  js  c++  java
  • Bill的挑战(bzoj 1879)

    Description

    Input

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

    Output

    1 2 1 a? ?b

    Sample Input

    50

    Sample Output

    对于30%的数据,T ≤ 5,M ≤ 5,字符串长度≤ 20;
    对于70%的数据,T ≤ 5,M ≤ 13,字符串长度≤ 30;
    对于100%的数据,T ≤ 5,M ≤ 15,字符串长度≤ 50。
    /*
      以后要多写状压DP啊,感觉好神的样子。
      我们设f[i][j]为T串已经匹配了i位,且与n个字符串是否匹配的集合为j
      为了方便转移,设g[i][j]为第i个字母是j的可匹配集合。 
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define mod 1000003
    using namespace std;
    char s[20][60];
    int g[60][30],f[60][33000],n,k;
    void work(){
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        int len=strlen(s[1]);
        for(int i=0;i<len;i++)
            for(int j=0;j<26;j++)
                for(int k=0;k<n;k++)
                    if(s[k][i]=='?'||s[k][i]==j+'a')
                        g[i][j]|=(1<<k);
        int N=1<<n;f[0][N-1]=1;
        for(int i=0;i<len;i++)
            for(int j=0;j<N;j++)
                if(f[i][j])
                    for(int k=0;k<26;k++)
                        f[i+1][j&g[i][k]]=(f[i+1][j&g[i][k]]+f[i][j])%mod;
        int ans=0;
        for(int j=0;j<N;j++){
            int tot=0;
            for(int p=0;p<n;p++)
                if(j&(1<<p))tot++;
            if(tot==k)ans=(ans+f[len][j])%mod;
        }
        printf("%d
    ",ans);
    }
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            memset(f,0,sizeof(f));
            memset(g,0,sizeof(g));
            work();
        }
        return 0;
    }
  • 相关阅读:
    linux-溢出程序
    linux下edb调试器
    IOS 学习
    xcode+OC基础学习
    mailcarrier25 EMAIL程序 典型覆盖返回地址XPSP3
    easyftpsvr-1.7.0.2 POC
    VS2010 MSDN Help Library 出现问题处理方法
    虚拟机XP 连接 虚拟机 linux
    修复文章···
    枚举所有进程所有模块,删除制定进程
  • 原文地址:https://www.cnblogs.com/harden/p/6257807.html
Copyright © 2011-2022 走看看