• BZOJ-1879 Bill的挑战 状态压缩DP


    MD....怎么又是状压.......
    

    1879: [Sdoi2009]Bill的挑战
    Time Limit: 4 Sec Memory Limit: 64 MB
    Submit: 537 Solved: 280
    [Submit][Status][Discuss]

    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。

    HINT

    Source
    Day2

    一看数据范围,50?感觉不能状压啊...哦,M<=15.....
    

    思路比较简单:
    f【i】【j】表示 匹配到第i位,时状态为j的方案数;
    具体的转移:
    f[i+1][j&(g[i][l])]+=f[i][j],f[i+1][j&(g[i][l])]%=p;
    用g来存储状态,枚举状态即可;

    PS:当天晚上调了20多分钟没调完....被YveH神犇叫去颓废了,Carry了他一盘后睡觉去了...第二天调完1A辣
    

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define p 1000003
    int t,n,k;
    char s[20][60];
    
    int f[60][1<<15],g[60][1<<5];
    void DP()
    {
        memset(f,0,sizeof(f)); memset(g,0,sizeof(g));
        int len=strlen(s[1]);
        for (int i=0; i<len; i++)
            for (int j=1; j<=n; j++)
                for (int l=0; l<26; l++)
                    if (s[j][i]=='?' || s[j][i]=='a'+l)
                        g[i][l]|=1<<(j-1);
        f[0][(1<<n)-1]=1;
        for (int i=0; i<len; i++)
            for (int j=0; j<(1<<n); j++)
                if (f[i][j]!=0)
                    for (int l=0; l<26; l++)
                        f[i+1][j&(g[i][l])]+=f[i][j],f[i+1][j&(g[i][l])]%=p;
        int ans=0;
        for (int i=0; i<(1<<n); i++)
            {
                int now=i,tmp=0;
                while (now) tmp+=now&1,now>>=1;
                if (tmp==k) ans=(ans+f[len][i])%p;
            }
        printf("%d
    ",ans);
    }
    
    int main()
    {
        t=read();
        while (t--)
            {
                n=read(),k=read();
                for (int i=1; i<=n; i++)
                    scanf("%s",s[i]);
                DP();
            }
        return 0;
    } 
  • 相关阅读:
    阿里早期Android加固代码的实现分析
    如何利用C++的time头文件获取系统时间
    Python编写基于socket的非阻塞多人聊天室程序(单线程&多线程)
    Dalvik模式下在Android so库文件.init段、.init_array段构造函数上下断点
    手动绕过百度加固Debug.isDebuggerConnected反调试的方法
    request使用代理
    requests爬取豆瓣热门电视剧
    scrapy-继承默认的user-agent 中间件
    scrapy-下载器中间件 随机切换user_agent
    scrapy 直接在编辑器运行
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346153.html
Copyright © 2020-2023  润新知