1. 程式人生 > >51nod 1277 KMP 前綴出現次數

51nod 1277 KMP 前綴出現次數

com ace ++ algorithm () int col 出現次數 names

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; }

51nod 1277 KMP 前綴出現次數