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;
    }
  • 相关阅读:
    触发器
    数据库function和procedure
    java连接数据库
    单例模式
    python入门相关笔记
    ubuntu 系统备份到移动硬盘(tar) 还原到另一台电脑
    大白菜pe 通用pe 安装心得
    18 java 代理模式 (转)
    5 HBase 常用Shell命令
    1、shell 简介
  • 原文地址:https://www.cnblogs.com/Egoist-/p/7435754.html
Copyright © 2011-2022 走看看