zoukankan      html  css  js  c++  java
  • 1368. 最长前缀

    状态表示:

    (f(i)):前缀(s[1 sim i])能否由子串集合中的元素表示。

    (f(i))只有(true)(false)两种取值。

    状态转移:

    对每个子串(p[i]),若(s[i])大小为(p[i])长度的后缀与(p[i])匹配,则有如下转移:

    [f(i) |= f(i-p[i].size()) ]

    const int N=2e5+10;
    bool f[N];
    string a[210];
    string s;
    int n;
    
    int main()
    {
        while(cin>>s, s[0] != '.')
            a[n++]=s;
    
        s.clear();
        string line;
        while(cin>>line) s += line;
    
        f[0]=true;
        int res=0;
        for(int i=1;i<=s.size();i++)
            for(int j=0;j<n;j++)
            {
                int t=a[j].size();
                if(i >= t && s.substr(i-t,t) == a[j])
                    f[i] |= f[i-t];
                if(f[i]) res=i;
            }
        
        cout<<res<<endl;
        //system("pause");
        return 0;
    }
    

    判断某一后缀是否由子串集合中的元素组成,不必枚举所有子串,可以借助哈希表优化。由于子串的长度不超过(10),所以按长度从小到大枚举后缀,判断该后缀是否在哈希表(子串集合)中。

    const int N=2e5+10;
    bool f[N];
    unordered_set<string> S;
    string s;
    int n;
    
    int main()
    {
        while(cin>>s, s[0] != '.')
            S.insert(s);
    
        s.clear();
        string line;
        while(cin>>line) s += line;
    
        f[0]=true;
        int res=0;
        for(int i=1;i<=s.size();i++)
            for(int j=1;j<=min(i,10);j++)
            {
                string t=s.substr(i-j,j);
                if(S.count(t))
                    f[i] |= f[i-j];
                if(f[i]) res=i;
            }
    
        cout<<res<<endl;
    
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    全排列 next_permutation()函数
    hdu1247
    hdu3518
    pku2774 求最长公共子串
    hdu3460 Ancient Printer
    pku2001
    pku 3261
    NOI.AC#2007light【根号分治】
    CF1370F2The Hidden Pair(Hard Version)【交互题,二分】
    P3335[ZJOI2013]蚂蚁寻路【dp】
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14849776.html
Copyright © 2011-2022 走看看