zoukankan      html  css  js  c++  java
  • [HNOI2004][bzoj1212] L语言 [Trie+dp]

    题面

    传送门

    思路

    无后效性

    显然,不管某个前缀的理解方式是怎么样的,如果它能被理解,那么前面的决策对于后面的决策而言都是等价的

    因此这题可以DP

    DP方程

    令$dp[i]$表示前缀i是否能被理解

    那么,显然状态转移方程为:

    $dp[i]=dp[i]||dp[j];;(s[j+1...i]in D)$

    也就是说,现在我们的问题转化为:求第i位往前数可以匹配的所有单词

    因为这个往前数的方向和方式是唯一的,所以我们想到一个字符串数据结构:$Trie$

    $Trie$

    一个非常常规的想法,就是把所有单词插到$trie$里面,然后用这个往前数的子串去匹配单词

    但是这样有一个问题:我们是从$trie$的某一个深层次位置往根匹配,而这样的开始节点可能有多个

    这个问题出现的根本原因,是因为我们是拿一个后缀去匹配单词的,但是我们的$trie$以前缀方式保存

    所以,我们只要把$trie$保存的方式从前缀变成后缀就好了

    我们把所有单词反向,插入$trie$里面

    求$dp[i]$的时候,从$s[i]$开始往前,$trie$从根节点开始,向下走,走到一个单词的结尾(实际上反过来以后就是单词的开头),就用这个位置更新$dp[i]$

    总时间效率上限:

    $Oleft(mleft(10strlen(s)+Oleft(Trie ight) ight) ight)=Oleft(2ast10^8 ight)$

    但是一般达不到这么多,我的代码最后一个点272ms,还是很稳的

    实在不行,给评测机吸氧啊【雾】

    Code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node{//trie节点
        int num,son[27];
        node(){num=0;memset(son,0,sizeof(son));}
    }x[210];
    int n,m,dp[1000010],cnt;char a[1000010];
    void add(char s[20]){//插入单词
        int len=strlen(s),cur=0,i;
        for(i=len-1;i>=0;i--){
            if(!x[cur].son[s[i]-'a']) x[cur].son[s[i]-'a']=++cnt;
            cur=x[cur].son[s[i]-'a'];
        }
        x[cur].num++;
    }
    void check(char s[],int pos){
        int cur=0,i,flag=0;
        for(i=pos-1;i>=0;i--){
            if(!x[cur].son[s[i]-'a']) break;
            cur=x[cur].son[s[i]-'a'];if(x[cur].num&&dp[i]) flag=1;
        }
        dp[pos]=flag;
    }
    int main(){
        scanf("%d%d",&n,&m);int i,len,l,j,ans;char s[20];
        for(i=1;i<=n;i++) scanf("%s",s),add(s);
        for(l=1;l<=m;l++){
            scanf("%s",a);memset(dp,0,sizeof(dp));
            dp[0]=1;len=strlen(a);ans=0;
            for(i=1;i<=len;i++){
                check(a,i);
                if(dp[i]) ans=max(i,ans);
            }
            printf("%d
    ",ans);
        }
    }
    
  • 相关阅读:
    【Jquery系列】详解Jquery对象和Dom对象
    将博客搬至CSDN
    【工具篇】.NET开发常用工具
    【ASP.NET MVC系列】浅谈jqGrid 在ASP.NET MVC中增删改查
    【SqlServer】【问题收集】必须声明标量变量
    【SqlServer】【问题收集】删除同一张表中完全相同的记录
    【SqlServer】【问题收集】阻止保存要求重新创建表的更改
    Java多线程编程中Future模式的详解<转>
    Java后端,应该日常翻看的中文技术网站<转>
    PostgreSql 函数
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8906238.html
Copyright © 2011-2022 走看看