import java.io.*; import java.util.*; import java.awt.*; class worms_judge { public Scanner sc; public PrintStream ps; public String toString() { return "worms_judge"; } // Class to hold a rule: A->BC public class Rule { // Actually, index -> a b // where index, a and b are integers public int index, a, b; public Rule( char chs[] ) { // Convert from chars to ints index = (int)(chs[0]-'A'); a = (int)(chs[1]-'A'); b = (int)(chs[2]-'A'); } public String toString() { return ""+(char)(index+'A')+"->"+(char)(a+'A')+(char)(b+'A'); } }; // memo[][] is for memoization - memo[i][j][c] will remember the best (shortest) // number of days to produce the subsequence from i to j in the original worm, // if you start from char c (represented as an int). int memo[][][]; // For each cell, remember a list of rules that say what that cell can grow into LinkedList rules[]; // The characters of the original worm char worm[]; // Compute the least number of days it would take to generate the // subsequence of the original worm from lo to hi, if you started // with cell ch. public int fastest( int ch, int lo, int hi ) { // Look at the memo field to see if we've already computed this // -1 is used as a flag that it hasn't been computed yet. if( memo[lo][hi][ch]<0 ) { // Start out with something unreasonably big int best = 10000; // if lo==hi, then we're talking about a single cell. if( lo==hi ) { // If this spot in the worm matches that cell, then it takes 0 days. // Otherwise, you can't get there. Use an unreasonably large number. best = (worm[lo]==(char)(ch+'A')) ? 0 : 10000; } else { // If lo!=hi, then we've got to apply a rule. // So, go through all the rules that start with ch for( Rule rule : rules[ch] ) { // We've got to split the subsequence into two smaller subsequences. // If the rule is X->AB, then the first subsequence has to be generated by A, // and the second by B. // // Start by going through all the possible split points. (Split between i and i+1) for( int i=lo; i(); } // Read the rules for( int i=0; i