洛谷 P2031 脑力达人之分割字串

题目传送门

解题思路:

f[i]表示到第i位可获得的最大分割次数,对于每个f[i]都可由其符合条件的前缀转移过来,条件就是当前串除了前缀的剩余字符里有所给单词,然后一看,这不是在剩余字符里找有没有所给单词吗?所以果断KMP,其实本题好像不用KMP,暴力模拟就可以,但是为了练习KMP装逼,所以就写一下.

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 
 4 using namespace std;
 5 
 6 string l,p,a[501];
 7 int n,kmp[501][301],f[501]; 
 8 
 9 inline int max(int s,int d) {
10     if(s > d) return s;
11     return d;
12 }
13 
14 int main() {
15     cin >> p;
16     l = " " + p;
17     scanf("%d",&n);
18     for(int i = 1;i <= n; i++) {
19         cin >> p;
20         a[i] = " " + p;
21         int len = a[i].length() - 1,k = 0;
22         for(int j = 2;j <= len; j++) {
23             while(k != 0 && a[i][j] != a[i][k+1]) k = kmp[i][k];
24             if(a[i][j] == a[i][k+1]) k++;
25             kmp[i][j] = k;
26         }
27     }
28     for(int i = 1;i <= l.length() - 1; i++) {
29         for(int j = 1;j <= i; j++) {
30             string u = " " + l.substr(j,i-j+1);
31             int o;
32             bool vis = 0;
33             for(int k = 1;k <= n; k++) {
34                 o = 0;
35                 for(int p = 1;p <= u.length() - 1; p++) {
36                     while(o != 0 && u[p] != a[k][o+1]) o = kmp[k][o];
37                     if(u[p] == a[k][o+1]) o++;
38                     if(o == a[k].length() - 1) {
39                         vis = 1;
40                         break;
41                     }
42                 }
43                 if(vis) break;
44             }
45             if(vis)
46                 f[i] = max(f[i],f[j-1] + 1);
47         }
48     }
49     printf("%d",f[l.length()-1]);
50     return 0;
51 }
原文地址:https://www.cnblogs.com/lipeiyi520/p/12375226.html