Topic Portal
Test Instructions: Training guide P250
Analysis: DFS memory search, the range or the graph is a known string composition of the automaton diagram, then by | (1 << i) denotes the inclusion of the I string, if the length is Len, and st = = (1 << m)-1 is possible. Printing is similar to the previous.
#include <bits/stdc++.h>using namespace Std;typedef long long ll;const int N = + 5;const int NODE = ten * + 5;c onst int M = (1 <<) + 5;const int SIZE = 26;int N, m;char str[12];struct AC {int ch[node][size], Val[node], Fail[node], Last[node], sz; ll Dp[node][n][m]; int out[n]; void Clear (void) {memset (ch[0], 0, sizeof (ch[0])); SZ = 1; } int idx (char c) {return C-' a '; } void Insert (char *s, int v) {int u = 0; for (int c, i=0; s[i]; ++i) {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 << v); } void Build (void) {queue<int> que; fail[0] = 0; for (int c=0; c<size; ++c) {int u = ch[0][c]; if (u) {fail[u] = 0; Last[u] = 0; Que.push (U); }} while (!que.empty ()) {int r = Que.front (); Que.pop (); for (int c=0; c<size; ++c) {int &u = ch[r][c]; if (!u) {u = ch[fail[r]][c]; continue; } que.push (U); int v = fail[r]; while (v &&!ch[v][c]) v = fail[v]; Fail[u] = Ch[v][c]; Val[u] |= Val[fail[u]; Last[u] = Val[fail[u]]? Fail[u]: Last[fail[u]; }}} void print (int now, int len, int st) {if (len = = N) {for (int i=0; i<len; + +i) {printf ("%c", Out[i] + ' a '); } puts (""); return; } for (int c=0; c<size; ++c) {if (Dp[ch[now][c]][len+1][st|val[ch[now][c]] > 0) { Out[len] = c; Print (Ch[now][c], Len + 1, st | Val[ch[now][c]]); }}} ll DP (int now, int len, int st) {ll &ans = dp[now][len][st]; if (ans! =-1) return ans; if (len = = N) {if (st = = (1 << m)-1) return ans = 1; else return ans = 0; } ans = 0; for (int c=0; c<size; ++c) {ans + = DP (Ch[now][c], Len + 1, st | Val[ch[now][c]]); } return ans; } void Run (void) {memset (DP,-1, sizeof (DP)); ll ans = DP (0, 0, 0); printf ("%lld suspects\n", ans); if (ans <=) {print (0, 0, 0); }}}ac;int Main (void) {int cas = 0; while (scanf ("%d%d", &n, &m) = = 2) {if (!n &&!m) break; Ac.clear (); for (int i=0; i<m; ++i) {scanf ("%s", &STR); Ac.insert (str, i); } ac.build (); printf ("Case%d:", ++cas); Ac.run (); } return 0;}
DP (Memory Search) + AC automaton LA 4126 Password Suspects