AC Automaton +DP change in string '? ' Make the number of matches in the dictionary up to Codechef Lucy and Question Marks

Source: Internet
Author: User

Lucy and Question Marks

long ago Lucy had written some sentences in her textbook. She had recently found those her notes. But because of the large amount of time is had passed, some letters became difficult to read. Her notes is given to you as a string with question marks in places of letters that is impossible to read.

lucy remembers" those sentences definitely made some sense. So now she wants to restore them. She thinks that's the best-of-the-question marks by Latin letters in such a. Sum of occurrences of the strings from her dictionary in it is maximal. And it is the normal if some word occurs in she dictionary or more times. In this case you just has to count every word as much times as it occurs in the dictionary.

You'll be given the string itself and the dictionary. Please output the maximal possible number of occurrences of dictionary words and lexicographically minimal string with thi s number of occurrences.

Input

the first line of the input contains an integer t  denoting The number of test cases. The description of t  test cases follows.

the first line of every test case consists of the Integers n   And m  -the length of the string, written by Lucy and the number of words in the Dictionar Y. The second line of the test case consists of the string itself- n characters, either A question mark or a small Latin letter.
then, m  lines follow. Each line consist of a single string of small Latin letters-the word from the dictionary.

Output

For each test case, output a, lines. The first line should contain the maximal number of occurrences. The second line should contain lexicographically minimal string with the maximal number of occurrences of the words from T He dictionary.

Example
Input:Panax 4??????? Abbaabax5 3?ac?? Bacdcdexa8 2?a?b?c?decxdzzzOutput:9abababa2bacde1aaabecxd
scoring

Subtask 1 (points):T= 1, <=N<= 8, 1 <=M<= 10. Only the characters A, B and C and question marks occur in the string. Only the characters A, B, and C occur in the dictionary words. All the words in the dictionary consist for no more than letters.

Subtask 2 (points):T= 1, <=N<=, 1 <=M<= 100. Only the characters a, B and question marks occur in the string. Only the characters A and b occur in the dictionary words. All the words in the dictionary consist for no more than letters.

Subtask 3 (points):T= ten, 1 <=N<=, 1 <=M<= 1000. Total length of the dictionary strings would not exceed 1000.

Time limit for the last subtask equals to 2 sec. For the first and the subtasks it is 1 sec.

qmarks-editorialproblem Link:

Practice
Contest

Difficulty:

Easy-medium

pre-requisites:

Aho-corasick, DP

Explanation:

In order to pass the first sub task It's sufficient to implement exponential-time brute force solution. In order to go further some knowledge about Aho-corasick Algo'll be required. A lot of articles on Aho-corasick can is found on the net.

Let ' s solve the inverse problem first. Consider that we have a set of stringsDand a stringTAnd now it's required to calculate the total number of occurences in the strings fromDInchS. This problem are a standard for Aho-corasick Algo. The standard solution builds a trie from the set of stringsDWith O (total length of all the strings fromD) nodes. Then, suffix links is calculated and with the usage of suffix links It's possible to calculate the number of strings that End in every node of a trie and in every it ' s suffix. The next step is turning a trie in the automaton with O (States*alphabet) transitions. After this, you'll have a automaton on which your can makeNSteps in order to calculate the number of occurences all the required substrings. This is the brief description of the inverse problem solution. More detailed description can being found in almost all Aho-corasick tutorial, because this "inverse" problem is actually a W Ell known one.

now, how to solve the original problem. There is a DP soltuion. As it was mentioned before, there ' ll is O (total length of strings from  D ) states in the automaton. So it's possible to has a DP state of the form (number of letters already processed, current position in the automaton). The transition then was quite straightforward:if the current symbol is a question mark and then can has a possible Choi Ces. Otherwise, the choice is unique-you can does not use all the symbols but the current one. This can get the maximal number of occurences.

in order to restore the string itself, you can act greedily. You can iterate through the symbols of the string  S and starting from the first one. If the current character are a letter, then there's only one choice. Otherwise, you can iterate through all the possible characters, namely ' a ' to ' Z ' and choose the transition to the State W ith the maximal DP value in it (if there is several such transitions, you can choose the one with the minimal character). It becomes possible if your DP state was (the size of the current suffix, the position in the automaton), because adding a symbol is just a transition from one suffix to another, smaller one and in this case, the DP would contain all the Necessa Ry information about the remaining part of the string.

Setter ' s solution:

Can is found here

Tester ' s solution:

Can is found here

#include <iostream> #include <cstring> #include <cstdio> #include <algorithm>using namespace Std;int t,n,m,i,num,q,ls,j,trie[1005][26],enwei[1005],g[1005][26],dp[1005][1005],c,choi,link[1005],pv[1005],pch [1005],ew[1111];char a[1005],s[1005];int getlink (int k); int Go (int k,int j); int getlink (int k) {//suffix link standard CA Lculationif (link[k]==0) if (k==1| | pv[k]==1) Link[k]=1;else Link[k]=go (GetLink (Pv[k]), pch[k]); return link[k];} int Go (int k,int j) {//Aho-corasick ' s Automaton transitionif (g[k][j]==0) if (trie[k][j]!=0) g[k][j]=trie[k][j];elseg[k] [J]=k==1?1:go (GetLink (k), j); return g[k][j];} int main (int argc, char * const argv[]) {scanf ("%d", &t); T t--) {scanf ("%d%d", &n,&m), for (i=1;i<=n;i++) {A[i]=getchar (); (a[i]< ' A ' | | A[i]> ' z ') && (a[i]!= '? ')) A[i]=getchar ();} Num=1;gets (s); for (i=1;i<=m;i++) {gets (s); Ls=strlen (s); Q=1;for (j=0;j<ls;j++) if (!trie[q][s[j]-' a ']) {// Building the trietrie[q][s[j]-' a ']=++num; New TRANSITIONPV[NUM]=Q;PCH[num]=s[j]-' a '; Parent Vertice and character for the Nodeq=num;} Else q=trie[q][s[j]-' a '];++enwei[q]; Number of strings the end in this node}for (i=1;i<=num;i++) {//calculating the number of strings, the end in the nod E and all it ' s suffixesj=i;ew[j]=0;while (j>1) {Ew[i]+=enwei[j];j=getlink (j);}} for (i=1;i<=num;i++) enwei[i]=ew[i];for (i=0;i<=n;i++) for (j=1;j<=num;j++) dp[i][j]=-1000000000; DP initialization//DP[I][J]-answer for the substring [i; N] When the current node of the automaton is Jfor (j=1;j<=num;j++) dp[n][j]=enwei[j]; for (i=n-1;i>=0;i--) for (j=1;j<=num;j++) {//DP calculationif (a[i+1]== '? ') for (c=0;c<26;c++) Dp[i][j]=max (Dp[i][j],enwei[j]+dp[i+1][go (j,c)); else Dp[i][j]=max (dp[i][j],enwei[j]+dp[i+1 ][go (j,a[i+1]-' a ')]);} printf ("%d\n", dp[0][1]); Optimal Result:all the characters of the string is processed and we start in the first node o) for (q=1,i=1;i<=n;i++) {if (a[i]!= '? ') choi=a[i]-' a '; else{//If there ' s only one oPtionchoi=0;for (j=0;j<26;j++) if (Dp[i][go (q,j)]>dp[i][go (Q,choi)]) choi=j; Otherwise we should just take the most optimal One}putchar (' a ' +choi); Q=go (Q,choi);} Puts (""); for (i=1;i<=num;i++) {enwei[i]=link[i]=pv[i]=pch[i]=ew[i]=0;for (j=0;j<26;j++) trie[i][j]=g[i][j]=0    ;}} return 0;}

#include <cstdio> #include <memory.h> #include <cmath> #include <iostream> #include < Algorithm> #include <string>using namespace std;const int inf = 1e8;int I, j, N, M, V, Cnt;char a[1033];int t[1033 ][26];int pch[1033], Pv[1033];int terminal[1033];int reach[1033], link[1033];int mem[1033][26];int F[1003][1003];char Q;int Go (int v, char c), int get_link (int v) {//printf ("%d\n", V), if (link[v] = = 0) if (v = = 1 | | pv[v] = = 1) link[v] = 1;els E Link[v] = Go (Get_link (Pv[v]), Pch[v]); return link[v];} int go (int v, char c) {if (mem[v][c] = = 0) if (t[v][c]! = 0) Mem[v][c] = T[v][c];else if (v = = 1) mem[v][c] = 1;else mem[v][ c] = Go (Get_link (v), c); return mem[v][c];} int main () {//freopen ("Input.txt", "R", stdin),//freopen ("Output.txt", "w", stdout), int tc;scanf ("%d", &AMP;TC), while ( tc--) {memset (mem, 0, sizeof), memset (t, 0, sizeof (t)), memset (link, 0, sizeof), memset (terminal, 0, sizeof ( Terminal)); memset (reach, 0, sizeof (REACH)), scanf ("%d%d\n", &n, &m); foR (i = 1; I <= n; i++) A[i] = GetChar (); scanf ("\ n"); int cnt = 1, v;for (i = 1; I <= m; i++) {q = GetChar (); v = 1;while (q! = ' \ n ') {//putchar (q); Q-= ' a '; if (t[v][q] = = 0) {Cnt++;t[v][q] = cnt;pch[cnt] = q;pv[cnt] = V;} v = t[v][q];q = GetChar ();} terminal[v]++;//printf ("\ n");} for (i = 1; l <=n; i++) for (j = 1; J <= CNT; j + +) F[i][j] =-inf;for (i = 1; I <= cnt; i++) {v = i;while (V > 1) {Reach[i] + = Terminal[v];v = Get_link (v);}} for (i = 1; I <= cnt; i++) F[n + 1][i] = reach[i];for (i = n, i > 0; i--) for (j = 1; J <= CNT; j + +) {if (a[i]! = '?) ') F[i][j]=f[i + 1][go (J, A[i]-' a ')] + reach[j];else{for (q = 0; q < n; q++) f[i][j] = max (F[i][j], F[i + 1][go (j, Q) ] + reach[j]);}} printf ("%d\n", f[1][1]); v = 1;for (i = 1; I <= n; i++) {if (a[i] = = '? ') {q = ' a '; int best = F[i + 1][go (V, 0)];for (char c = 1; c < D; C + +) if (f[i + 1][go (V, c)] > Best) {best = F[i + 1][g O (V, c)];q = C + ' a ';}} else q = a[i];p rintf ("%c", q); v = Go (V, Q-' a ');} printf ("\ n");}}



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

AC Automaton +DP change in string '? ' Make the number of matches in the dictionary up to Codechef Lucy and Question Marks

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.