标签:clu blog online targe for void stream 倒序 next数组
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; }
标签:clu blog online targe for void stream 倒序 next数组
原文地址:http://www.cnblogs.com/Egoist-/p/7435754.html