zoukankan      html  css  js  c++  java
  • 51nod 1277 KMP 前缀出现次数

    51NOD 1277:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277

    跟HDU 6153还挺像的:http://www.cnblogs.com/Egoist-/p/7435573.html

    相比与上面那个题,这个还要相对简单一些,只需要处理模式串自己就好了。

    一开始写麻烦了,直接套了HDU6153的代码,后来发现……他就是个模式串本身的匹配,我干嘛弄那么麻烦Orz

    题意:找前缀长度*出现次数的最大值,长度好说,问题就在于求出现次数了

    最容易得到的前缀的长度和出现次数是模式串本身,也就是(len,1)(长度,出现次数);

    而在处理next[i]时,长度为i的前缀至少出现一次,那么我们用num[i]记录前缀[0……i]的出现次数,全部填充为1;

    与HDU6153一样,在计数前缀i的出现次数时,由于kmp减少回溯次数的特性,省略了相同前缀的计数,

    但是由于处理的是前缀,[0,next[i]]出现的前缀,在[0,i]中必然出现,倒序,num[next[i]]+num[i]即可;

    (至于为什么是倒序,emmmm,有种DP的感觉呢……为了减少next数组处理部分的改写(好吧其实是我懒),

    只有模式串本身,长度为len的前缀的出现次数是已知的,num[i]时是由num[i+1...len]得来的)

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAX = 100000;
    int nextt[MAX + 10];
    int num[MAX + 10];
    char s[MAX + 10];
    int t,len;
    void getnext()
    {
        int p=0, k = -1;
        nextt[0] = -1;
        while (p < len)
        {
            if (k == -1 || s[p] == s[k])
            {
                p++;k++;
                nextt[p] =k;
             }
            else k = nextt[k];
        }
    }
    int main()
    {
        while (cin >> s)
        {
            len = strlen(s);
            fill(num, num+len+1, 1);
            getnext();
            int maxx = 0;
            for (int i = len; i > 0; i--)
            {
                num[nextt[i]] += num[i];
                maxx = max(maxx, num[i]*i);
            }
            cout << maxx << endl;
        }
        return 0;
    }
  • 相关阅读:
    1386. 安排电影院座位
    1123. 最深叶节点的最近公共祖先
    375. 猜数字大小 II
    未能在system.drawing中找到bitmap
    856. 括号的分数
    140. 单词拆分 II
    5909. 并行课程 III
    typora + ImgHosting (一款不会存储图片的图床实现)
    IDEA插件:search with bing、search with baidu
    多吉搜索美化
  • 原文地址:https://www.cnblogs.com/Egoist-/p/7435754.html
Copyright © 2011-2022 走看看