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;
}
时间: 2024-12-13 06:48:56

51nod 1277 KMP 前缀出现次数的相关文章

hdu6153 A Secret CCPC网络赛 51nod 1277 KMP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6153 题意: 给出两个字符串S1,S2,求S2的所有后缀在S1中出现的次数与其长度的乘积之和. 思路: CCPC网络赛题解: https://post.icpc-camp.org/d/714-ccpc-2017 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277   是一样的 将s1,s2翻转,转化为求前缀在s1中出

51nod 1277 字符串中的最大值

题目链接 51nod 1277 字符串中的最大值 题解 对于单串,考虑多串的fail树,发现next数组的关系形成树形结构 建出next树,对于每一个前缀,他出现的次数就是他子树的大小 代码 #include<cstdio> #include<cstring> #include<algorithm> inline int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9

HDOJ3336 Count the string 【KMP前缀数组】+【动态规划】

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4212    Accepted Submission(s): 1962 Problem Description It is well known that AekdyCoin is good at string problems as well as n

51Nod 1277 字符串中的最大值(KMP,裸题)

1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd. 给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值. 例如:S = "abababa" 所有的前缀如下: "a", 长度与出现次数的乘积 1 * 4 = 4, "ab",长度与出

51Nod 1277 字符串中的最大值 ( KMP &amp;&amp; DP )

题意 : 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd.给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.例如:S = "abababa" 所有的前缀如下: "a", 长度与出现次数的乘积 1 * 4 = 4, "ab",长度与出现次数的乘积 2 * 3 = 6, "aba", 长度与出现次数的乘积 3 * 3 = 9, "abab&

51nod 1277 字符串中的最大值(KMP算法)

分析: KMP算法:参考http://www.cnblogs.com/c-cloud/p/3224788.html,是一个线性处理字符串匹配问题的算法 在这里利用到next数组,记t[i]为长度为i的前缀出现的次数,显然t[n]=1.next[i]即为子串[0,i]的后缀与前缀重复的最长长度,因此可以统计一下next[i]的取值的个数,然后较长的前缀出现一次代表较短的前缀也一次,递推一下即可,复杂度为O(n). 1 #include<iostream> 2 #include<cstrin

HDU 3336 Count the string (KMP next数组运用——统计前缀出现次数)

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6375    Accepted Submission(s): 2947 Problem Description It is well known that AekdyCoin is good at string problems as well as nu

kmp(前缀出现次数next应用)

http://acm.hdu.edu.cn/showproblem.php?pid=3336 Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17068    Accepted Submission(s): 7721 Problem Description It is well known that Ae

HDU4300-Clairewd’s message(KMP前缀匹配后缀)

Clairewd's message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3228    Accepted Submission(s): 1248 Problem Description Clairewd is a member of FBI. After several years concealing in BUPT,