zoukankan      html  css  js  c++  java
  • bzoj千题计划207:bzoj1879: [Sdoi2009]Bill的挑战

    http://www.lydsy.com/JudgeOnline/problem.php?id=1879

    f[i][j] 表示匹配了i个字符,匹配字符串的状态为j的方案数

    枚举下一个字符是什么

    计算加上这个自字符之后新匹配到的状态s

    f[i+1][s]+=f[i][j]

    转移的时候判断如果f[i][j]==0,就不用枚举字符了

    没有这个复杂度在6e8,TLE

    其实可以预处理 g[i][j]表示已经匹配了长度为i,再加字符j 可以匹配到的状态

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int N=1<<15;
    const int mod=1000003;
    
    char s[16][51];
    
    int f[51][N];
    
    int bit[16];
    
    int count(int x)
    {
        int sum=0;
        while(x) 
        {
            sum+=x&1;
            x>>=1;
        }
        return sum;
    }
    
    int main()
    {
        bit[0]=1;
        for(int i=1;i<=15;++i) bit[i]=bit[i-1]<<1;
        int T;
        scanf("%d",&T);
        int n,t,m,len;
        int S,nj;
        int ans;
        while(T--)
        {
            scanf("%d%d",&n,&t);
            memset(f,0,sizeof(f));
            m=0;
            for(int i=1;i<=n;++i) 
            {
                scanf("%s",s[i]+1);
                len=strlen(s[i]+1);
                m=max(m,len);
            }
            S=bit[n];
            for(int i=0;i<26;++i)
            {
                nj=0;
                for(int j=1;j<=n;++j)
                    if(s[j][1]==i+'a' || s[j][1]=='?') nj+=bit[j-1];
                f[1][nj]++;
            }
            for(int i=1;i<m;++i)
                for(int j=0;j<S;++j)
                    if(f[i][j])
                        for(int k=0;k<26;++k)
                        {
                            nj=0;
                            for(int l=1;l<=n;++l)
                                if(j&bit[l-1])
                                    if(s[l][i+1]==k+'a' || s[l][i+1]=='?') 
                                        nj+=bit[l-1];
                            f[i+1][nj]+=f[i][j];
                            f[i+1][nj]-=f[i+1][nj]>=mod ? mod : 0;
                        }
            ans=0;
            for(int i=0;i<S;++i)
                if(count(i)==t)
                {
                    ans+=f[m][i];
                    ans-=ans>=mod ? mod : 0;
                }
            cout<<ans<<'
    ';
        }
    }

    1879: [Sdoi2009]Bill的挑战

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 919  Solved: 477
    [Submit][Status][Discuss]

    Description

    Input

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

    Output

    如题

    Sample Input

    5
    3 3
    ???r???
    ???????
    ???????
    3 4
    ???????
    ?????a?
    ???????
    3 3
    ???????
    ?a??j??
    ????aa?
    3 2
    a??????
    ???????
    ???????
    3 2
    ???????
    ???a???
    ????a??

    Sample Output

    914852
    0
    0
    871234
    67018
  • 相关阅读:
    强行删除带点的文件夹
    如何设置让iis服务器支持.apk文件的下载
    纯CSS下拉导航菜单
    <UL>中<li>标签前编号图片的简单调用
    滑动门效果【鼠标滑过鼠标单击两种】
    SQL Server中,NumricDecimalMoney三种字段类型的区别
    SQL Server 20个最常用的时间格式
    Gridview------Set BackgroundColor
    c# 中is 和 as 运算符
    SQL LEFT JOIN 关键字 SQL RIGHT JOIN 关键字 fulljoin
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8256761.html
Copyright © 2011-2022 走看看