• [HNOI2004]L语言


    题目描述

    标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的。现在你要处理的就是一段没有标点的文章。

    一段文章T是由若干小写字母构成。一个单词W也是由若干小写字母构成。一个字典D是若干个单词的集合。我们称一段文章T在某个字典D下是可以被理解的,是指如果文章T可以被分成若干部分,且每一个部分都是字典D中的单词。

    例如字典D中包括单词{‘is’, ‘name’, ‘what’, ‘your’},则文章‘whatisyourname’是在字典D下可以被理解的,因为它可以分成4个单词:‘what’, ‘is’, ‘your’, ‘name’,且每个单词都属于字典D,而文章‘whatisyouname’在字典D下不能被理解,但可以在字典D’=D+{‘you’}下被理解。这 段文章的一个前缀‘whatis’,也可以在字典D下被理解,而且是在字典D下能够被理解的最长的前缀。

    给定一个字典D,你的程序需要判断若干段文章在字典D下是否能够被理解。并给出其在字典D下能够被理解的最长前缀的位置。

     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    正解trie树,然而hash时间够,水过。

    注意dp要全部附零。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ull unsigned long long
    #define seed 13131
    struct node
    {
        int cnt;
        ull hs[25];
        void push(ull h){hs[++cnt] = h;}
    }p[15];
    int n,m;
    char s[15],a[2000050];
    int dp[2000050];
    ull has[2000050],k0[2000050];
    void make_has()
    {
        int len = strlen(a+1);
        for(int i=1;i<=len;i++)
            has[i]=seed*has[i-1]+a[i],dp[i]=0;
    }
    ull get_hs(int l,int r)
    {
        return has[r]-has[l-1]*k0[r-l+1];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s+1);
            int len = strlen(s+1);
            ull h = 0;
            for(int j=1;j<=len;j++)
                h = seed*h+s[j];
            p[len].push(h);
        }
        k0[0] = 1;
        for(int i=1;i<=2000020;i++)
            k0[i]=k0[i-1]*seed;
        for(int i=1;i<=m;i++)
        {
            scanf("%s",a+1);
            make_has();
            int len = strlen(a+1);
            dp[len+1]=0;
            for(int j=len;j>=1;j--)
            {
                for(int l=1;l<=10&&j+l-1<=len;l++)
                {
                    ull h = get_hs(j,j+l-1);
                    for(int w=1;w<=p[l].cnt;w++)
                    {
                        if(h==p[l].hs[w])
                        {
                            dp[j]=max(dp[j],dp[j+l]+l);
                            break;
                        }
                    }
                }
            }
            printf("%d
    ",dp[1]);
        }
        return 0;
    }
  • 相关阅读:
    Oracle 11 安装 提示环境不满足最低要求解决方案
    sys.argv[]的用法简明解释
    (转载)Pycharm 新版本打开md文件卡死-解决办法
    csv模块
    算法笔记——【动态规划】矩阵连乘问题——备忘录法
    Clion配置MingGW报错test cmake run with errors解决方法
    主定理(Master Theorem)与时间复杂度的计算
    UML笔记
    分治法+时间复杂度分析
    数字图像处理DIP 学习笔记
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9679704.html
Copyright © 2020-2023  润新知