zoukankan      html  css  js  c++  java
  • BZOJ1879 Bill的挑战

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

    本来是一道水题(~~~~(>_<)~~~~)。

    开始SB了,敲了个AC自动机dp,MLE

    发现数据中 '?' 好多呀 ~~~~(>_<)~~~~ 空间变$O(len^2)$

    然后去想朴素dp,枚举一下那些集合和T匹配,然后$O(n cdot 2^n)$ dp,又W又T一是爽。

    TLE 40:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    #define c(w,i) ((w>>i)&1)
    #define mod 1000003
    #define LL long long
    #define MP(x,y) make_pair(x,y)
    #define fir first
    #define sec second
    
    using namespace std;
    
    int n,K,cnt;
    char S[110][110],T[110];
    LL f[110][26];
    vector<pair<int,char> > v[110];
    
    LL calc(int w){
        for(int i=0;i<n;i++) T[i]='?';
        for(int i=0;i<cnt;i++)
            if(c(w,i)){
                for(int j=0;j<n;j++)
                    if(S[i][j]!='?'){
                        if(T[j]=='?'||T[j]==S[i][j])
                            T[j]=S[i][j];
                        else return 0;
                    }
            }
        memset(f,0,sizeof(f));
        for(int i=0,fl;i<cnt;i++)
            if(!c(w,i)){
                fl=0;
                for(int j=0;j<n;j++){
                    if(S[i][j]!='?' && T[j]!='?' && S[i][j]!=T[j])
                        fl=1;
                }
                if(!fl){
                    for(int j=0;j<n;j++){
                        if(S[i][j]!='?')
                            v[j].push_back(MP(i,S[i][j]));
                    }
                }
            }
        f[0][0]=1;
        for(int i=0;i<n;i++){
            for(int w=0;w<(1<<cnt);w++)
                if(f[i][w]){
                    for(char c='a';c<='z';c++){
                        if(T[i]!='?'&&T[i]!=c) continue;
                        int now=0;
                        for(int j=v[i].size()-1;~j;j--)
                            if(v[i][j].sec!=c) now|=(1<<v[i][j].fir);
                        f[i+1][now|w]+=f[i][w];
                    }
                }
        }
        return f[n][((1<<cnt)-1)&~w];
    }
    
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&cnt,&K);
            for(int i=0;i<cnt;i++) scanf("%s",S[i]);
            n=strlen(S[0]);
            LL ans=0;
            for(int w=0;w<(1<<cnt);w++){
                int tmp=0;
                for(int i=0;i<cnt;i++)
                    if(c(w,i)) tmp++;
                if(tmp!=K) continue;
                ans=(ans+calc(w))%mod;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    然后发现我是SB

    没有看完题呀,原来长度都相同。

    直接裸dp f[i][S] 表示T的前i位,n个串的匹配状态为S的方案数。

    注意因为长度都相同,只能从第一位开始匹配呀!!!

    然后水了。

    AC 100:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    #define c(w,i) ((w>>i)&1)
    #define mod 1000003
    
    using namespace std;
    
    int n,K,cnt,f[60][65536],cv[60][26];
    char S[20][60];
    
    int main(){
        freopen("test.in","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--){
            memset(f,0,sizeof(f));
            scanf("%d%d",&cnt,&K);
            for(int i=0;i<cnt;i++) scanf("%s",S[i]);
            n=strlen(S[0]);
            for(int i=0;i<n;i++){
                for(int t=0;t<26;t++){
                    cv[i][t]=0;
                    for(int j=0;j<cnt;j++){
                        if(S[j][i]=='?'
                            ||S[j][i]==t+'a') cv[i][t]|=(1<<j);
                    }
                }
            }
            f[0][(1<<cnt)-1]=1;
            for(int i=0;i<n;i++)
                for(int j=0;j<(1<<cnt);j++){
                    if(f[i][j]){
                        for(int t=0;t<26;t++)
                            (f[i+1][j&cv[i][t]]+=f[i][j])%=mod;
                    }
                }
            int ans=0;
            for(int w=0;w<(1<<cnt);w++){
                int tmp=0;
                for(int i=0;i<cnt;i++) if(c(w,i)) tmp++;
                if(tmp==K) (ans+=f[n][w])%=mod;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    cas改造随笔
    数字证书KeyTool使用(第二篇)
    debug.keystore文件不存在解决办法
    SSL安全解决方案(转)
    CAS SSO:汇集配置过程中的错误解决方法
    sso笔记
    获取指定月 获取指定日期是星期几
    协同过滤推荐算法总结
    Java动态代理深入解析
    分享一个前后端分离的轻量级内容管理框架
  • 原文地址:https://www.cnblogs.com/lawyer/p/4551188.html
Copyright © 2011-2022 走看看