HDU 3336 Count the String(KMP+DP)

http://acm.hdu.edu.cn/showproblem.php?pid=3336

题意:给出一个字符串,计算所有前缀在字符串中出现的次数。

思路:考虑KMP的next[]来解题。next[i]=j表示最大的j使得0~j==i-j~i。

        对于样例的next[]分析如下:

                  0   1   2   3

      a[]        a    b   a   b

      next[]   -1   0   0   1

     dp[i]表示子串a[0~i]共含有以a[i]为结尾的前缀的数目,则以a[i]结尾的前缀数就是自己本身加上以a[next[i]]结尾的前缀数,即dp[next[i]]。

     

 1 #include<iostream> 
 2 #include<cstring>
 3 using namespace std;
 4 
 5 const int maxn = 200000 + 5;
 6 
 7 int n;
 8 
 9 char a[maxn];
10 int next[maxn];
11 int dp[maxn];
12 
13 void get_next()
14 {
15     int i = -1, j = 0;
16     ::next[0] = -1;
17     int l = strlen(a);
18     while (j < l)
19     {
20         if (i == -1 || a[i] == a[j])
21             ::next[++j] = ++i;
22         else
23             i = ::next[i];
24     }
25 }
26 
27 int main()
28 {
29     //freopen("D:\\txt.txt", "r", stdin);
30     int t;
31     cin >> t;
32     while (t--)
33     {
34         cin >> n;
35         cin >> a;
36         get_next();
37         memset(dp, 1, sizeof(dp));
38         dp[0] = 0;
39         int sum = 0;
40         for (int i = 1; i <= n; i++)
41         {
42             dp[i] = dp[::next[i]] + 1;
43             sum += dp[i] % 10007;
44         }
45         cout << sum % 10007 << endl;
46     }
47     return 0;
48 }

 

posted @ 2017-01-30 10:47  Kayden_Cheung  阅读(222)  评论(0编辑  收藏  举报
//目录