zoukankan      html  css  js  c++  java
  • hdu 4534 郑厂长系列故事——新闻净化 夜

    http://acm.hdu.edu.cn/showproblem.php?pid=4534

    自动机+DP(状态压缩)

    整体思路应该很明确,但要注意一些细节方面的处理 否则会wa

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<map>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    
    using namespace std;
    const int MOD=1000000007;
    const int N=110;
    const int M=1610;
    const int K=26;
    struct nodeTrie
    {
        int v;
        int k;
        int fail;
        int next[K];
        void initialize()
        {
            v=0;
            k=0;
            fail=-1;
            memset(next,-1,sizeof(next));
        }
    }trie[M];
    int cnt,root;
    int to[M][K];
    char s[K];
    char words[N];
    int dp1[2][M][1<<8],dp2[2][M][1<<8];
    int getNewNode()
    {
        ++cnt;
        trie[cnt].initialize();
        return cnt;
    }
    void addWord(int p,char *s,int k,int l)
    {
        if(s[0]=='\0') return ;
        for(int i=0;s[i]!='\0';++i)
        {
            if(trie[p].next[s[i]-'a']==-1)
            trie[p].next[s[i]-'a']=getNewNode();
            p=trie[p].next[s[i]-'a'];
        }
        if(k==999)
        trie[p].k=(1<<(l-1));
        else if(k==-999)
        trie[p].k=-1;
        else
        trie[p].v=k;
    }
    int init(int n)
    {
        cnt=-1;
        root=getNewNode();
        int l=0;
        while(n--)
        {
            int k;
            scanf("%s %d",s,&k);//puts(s);cout<<k<<endl;
            if(k==999) ++l;
            addWord(root,s,k,l);
        }
        return l;
    }
    void bfs(int p)
    {
        trie[p].fail=root;
        queue<int>qt;
        qt.push(p);
        while(!qt.empty())
        {
            int y;
            int x=qt.front();qt.pop();
            for(int i=0;i<K;++i)
            if(trie[x].next[i]!=-1)
            {
                qt.push(trie[x].next[i]);
                if(x==root)
                {trie[trie[x].next[i]].fail=root;continue;}
                y=trie[x].fail;
                while(y!=root&&trie[y].next[i]==-1)
                y=trie[y].fail;
                if(trie[y].next[i]!=-1)
                trie[trie[x].next[i]].fail=trie[y].next[i];
                else
                trie[trie[x].next[i]].fail=root;
                int l=trie[x].next[i],r=trie[trie[x].next[i]].fail;
                if(trie[l].k==-1||trie[r].k==-1)
                trie[l].k=-1;
                else {trie[l].k=(trie[l].k|trie[r].k);trie[l].v+=trie[r].v;}
            }
        }
    }
    void makeTo(int n,int k)
    {
        for(int i=0;i<=n;++i)
        for(int j=0;j<k;++j)
        {
    
            int p=i;
            while(p!=root&&trie[p].next[j]==-1)
            p=trie[p].fail;
            if(trie[p].next[j]!=-1)
            to[i][j]=trie[p].next[j];
            else
            to[i][j]=root;
        }
    };
    int main()
    {
        //freopen("data.in","r",stdin);
        int T;
        scanf("%d",&T);
        for(int w=1;w<=T;++w)
        {
            int n;
            scanf("%d",&n);
            int h=(1<<init(n));
            bfs(root);
            makeTo(cnt,K);
            scanf("%s",words);
            int m=strlen(words);
            memset(dp1,0,sizeof(dp1));
            memset(dp2,0,sizeof(dp2));
            int M=0,P=0;
            for(int i=0;i<=m;++i)
            {
                for(int j=0;j<=cnt;++j)
                for(int l=0;l<h;++l)
                {dp1[(i+1)%2][j][l]=0;dp2[(i+1)%2][j][l]=0;}
                for(int j=0;j<=cnt;++j)
                for(int l=0;l<h;++l)
                {
                    if(dp1[i%2][j][l]==0&&(j>0||l>0)) continue;
                    if(l==(h-1))
                    {
                        if(M<dp1[i%2][j][l]||(M==dp1[i%2][j][l]&&P<dp2[i%2][j][l]))
                        {M=dp1[i%2][j][l];P=dp2[i%2][j][l];}
                    }
                    if(i==m) continue;
                    int r=to[j][words[i]-'a'];
                    if(dp1[(i+1)%2][j][l]<dp1[i%2][j][l]||
                       (dp1[(i+1)%2][j][l]==dp1[i%2][j][l]&&dp2[(i+1)%2][j][l]<dp2[i%2][j][l]))
                        {dp1[(i+1)%2][j][l]=dp1[i%2][j][l];dp2[(i+1)%2][j][l]=dp2[i%2][j][l];}
                    if(trie[r].k!=-1)
                    {
                        int k=(l|(trie[r].k));
                        if(dp1[(i+1)%2][r][k]<dp1[i%2][j][l]+1||
                       (dp1[(i+1)%2][r][k]==dp1[i%2][j][l]+1&&dp2[(i+1)%2][r][k]<dp2[i%2][j][l]+trie[r].v))
                        {dp1[(i+1)%2][r][k]=dp1[i%2][j][l]+1;dp2[(i+1)%2][r][k]=dp2[i%2][j][l]+trie[r].v;}
                    }
                }
            }
            printf("Case %d: ",w);
            if(M==0)
            printf("Banned\n");
            else
            printf("%d %d\n",m-M,P);
        }
        return 0;
    }
    

      

  • 相关阅读:
    #leetcode刷题之路32-最长有效括号
    #leetcode刷题之路31-下一个排列
    数据结构第一节 递归
    数据结构 第一节
    java基础 抽象类与接口
    Spring1
    java基础3。定义类
    java基础2。基本数据类型
    java基础1。面向对象
    丑数
  • 原文地址:https://www.cnblogs.com/liulangye/p/2999262.html
Copyright © 2011-2022 走看看