Test instructions: Give n (n<=4000) words and a string (len<=300000), to break the string into a number of words splicing, how many ways
Idea:Trie, first put the word into Trie, and then dp,dp[i] denotes the beginning of the first letter of the string, and then each state as long as the Trie tree found the corresponding letter beginning word, and then dp[i] = sum{dp[i + len (x)]} To make a state transition. This x is one of n words that can be queried with trie
Code
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int maxn = 300005; const int MOD = 20071027;int ch[maxn][26];int val[maxn];int sz;int idx (char c) {return C ' a ';} void Insert (char* s) {int u = 0; int len = strlen (s); for (int i = 0; i < len; i++) {int c = idx (s[i]); if (!ch[u][c]) {memset (Ch[sz], 0, sizeof (Ch[sz])); Val[sz] = 0; CH[U][C] = sz++; } u = Ch[u][c]; } Val[u] = 1;} void init () {sz = 1; memset (ch[0],0,sizeof (ch[0)); int m; scanf ("%d", &m); Char str[105]; while (m--) {scanf ("%s", str); Insert (str); }}int d[maxn];void find (int id, char* s) {D[id] = 0; int u = 0;//int len = strlen (s); for (int i = ID; s[i]; i++) {int c = idx (s[i]); if (!ch[u][c]) return; U = ch[u][c]; if (Val[u]) d[id] = (d[id]+d[i+1])%mod; }}void Solve (char* s) {int len = strlen (s); D[len] = 1; for (int i = len-1; I >= 0; i--) {Find (I, s); } printf ("%d\n", D[0]);} int main () {int cas = 0; Char S[MAXN]; while (scanf ("%s", s)! = EOF) {init (); printf ("Case%d:", ++cas); Solve (s); } return 0;}
Attention:
The Find function must not strlen (), otherwise the timeout t_t. Because each call will be one length, time complexity is 0 (n*n);
UVA 1401 Remember The Word (Trie + DP)