zoukankan      html  css  js  c++  java
  • BZOJ 2580 video game

      这个题目是老师添加到我们学校的oj上的,估计数据是改过了的吧。题意大概是给了n个串,让你构造出来一个长度不超过k的串,使得这n个串在构造出来的这个串中出现次数最大。这也是我的ac自动机+dp第一题。虽然理解的还不是那么透,但还是做出来了,之前因为dp数组开的过小,wa了好多遍。感觉dp跟ac自动机结合在一起,dp也不显得那么难了。

    ac代码:

    View Code
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    
    using namespace std;
    
    const int maxn=25;
    const int maxnum=1010;
    
    char s[maxn][maxn];
    int dp[maxnum][maxnum],n,k,line;
    
    struct node
    {
        int cnt;
        int index;
        node *fail;
        node *next[3];
    }memory[1000000];
    
    node *que[maxnum];
    
    node *createnode()
    {
        node *p=&memory[line];
        for(int i=0;i<3;i++)
            p->next[i]=NULL;
        p->cnt=0;
        p->fail=NULL;
        p->index=line++;
        return p;
    }
    
    class AC
    {
        public :
        node *root;
        AC()
        {
            root=NULL;
        }
        void insert(char *str)
        {
            int len=strlen(str);
            if(!root)
                root=createnode();
            node *loca=root;
            for(int i=0;i<len;i++)
            {
                int num=str[i]-'A';
                if(loca->next[num]==NULL)
                    loca->next[num]=createnode();
                loca=loca->next[num];
            }
            loca->cnt++;
        }
        void build()
        {
            std::queue<node *>s;
            while(!s.empty())
                s.pop();
            s.push(root);
            root->fail=NULL;
            while(!s.empty())
            {
                node *loca=s.front();
                s.pop();
                for(int i=0;i<3;i++)
                {
                    if(loca->next[i]!=NULL)
                    {
                        if(loca==root)
                            loca->next[i]->fail=root;
                        else
                        {
                            node *tmp=loca->fail;
                            while(tmp!=NULL)
                            {
                                if(tmp->next[i]!=NULL)
                                {
                                    loca->next[i]->fail=tmp->next[i];
                                    break;
                                }
                                tmp=tmp->fail;
                            }
                            if(tmp==NULL)
                                loca->next[i]->fail=root;
                        }
                        if(loca->next[i]->fail->cnt)
                            loca->next[i]->cnt+=loca->next[i]->fail->cnt;
                        s.push(loca->next[i]);
                    }
                    else if(loca==root)
                        loca->next[i]=root;
                    else
                        loca->next[i]=loca->fail->next[i];
                }
            }
        }
        int DP()
        {
            memset(dp,-1,sizeof(dp));
            dp[0][0]=0;
            for(int i=0;i<k;i++)
            {
                for(int j=0;j<line;j++)
                {
                    if(dp[i][j]==-1) continue;
                    for(int idx=0;idx<3;idx++)
                    {
                        if(memory[j].next[idx]==NULL)  continue;
                        int num=memory[j].next[idx]->index;
                        if(dp[i][j]+memory[num].cnt>dp[i+1][num])
                            dp[i+1][num]=dp[i][j]+memory[num].cnt;
                    }
                }
            }
            int ans=0;
            for(int i=0;i<=k;i++)
            {
                for(int j=0;j<line;j++)
                    ans=max(ans,dp[i][j]);
            }
            return ans;
        }
    };
    
    void data_in()
    {
        AC ac;
        memset(s,0,sizeof(s));
        line=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            ac.insert(s[i]);
        }
        ac.build();
        printf("%d\n",ac.DP());
        memset(s,0,sizeof(s));
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&k))
        {
            data_in();
        }
        return 0;
    }

    之后会陆续放上这一类的题目。

  • 相关阅读:
    系统建模之UML状态图[转载]
    [软件工程]TO B型IT软件企业在工程管理角度所存在的诸多问题
    [Linux]异常配置专题之重复配置的有效性:系统/环境变量 | hosts
    将本地图片Base64(代码摘抄)
    将网络图片Base64(摘抄笔记)
    Cordova基本使用(三)
    Tushare环境搭建
    用Python做量化交易Tushare平台获取数据
    java将ftl格式模板输出为word模板
    oracle数据库的row_num() over()使用方法
  • 原文地址:https://www.cnblogs.com/RainingDays/p/2779689.html
Copyright © 2011-2022 走看看