Zju1876 pku2564 edit step ladders
Question:
If words A and B can be obtained by adding, deleting, or modifying a letter and a is placed before B, then a can reach B. The lexicographically given n words (n <= 25000) require the maximum length of the reachable word string.
Analysis:
This is a typical deformation of the longest non-descending subsequence, but the comparison between words is notPartial OrderLink, soCannot use the LIS algorithm of O (nlogn). Use the most directO (N ^ 2)Can be solved.
Set f [I] to indicate the length of the longest sequence ending with the word I. Initial f [0] = 1. The word sequence is a [I]
State transition equation: F [I] = max {f [J] + 1, (0 <= j <I, a [I] And a [J] reachable )}
Determine whether two words can reach the time that requires O (LEN (A [I.
No matter how optimization is done, it's still tle ......
The most direct way is to make full use of the information in the question: "words are given in Lexicographic Order ". Obviously, this property can be used for binary search. The question is, what needs to be searched?
There are only three types of deformation between words. You can add letters, delete letters, and change letters. If the word A [I] is to find an reachable word a [J] in the previous I-1 word, then a [J] Must be smaller than the Lexicographic Order of a [I.
Therefore, when calculating f [I,Enumerate all the words s produced by a [I] deformation, and then look for S in the second part of the previous I-1 word.If a [J] = s, a [I] can be connected to a [J.
Here isRequired pruningThat is, the enumeration starts from small to large according to the Lexicographic Order. When the value of S is greater than a [I], the enumeration stops. According to the question information, the words before a [I] must be less than a [I] In the Lexicographic Order. I tried to remove this pruning and the result was still tle ......
This takes 2.9 s for zju and is faster than PKU.
It is more efficient to find out whether word s exists.Trie tree. Not very familiar ......
Highlights:
I can't do it during training, so I can think of solutions when I go to bed at night ......
Bytes ----------------------------------------------------------------------------------------------------------
/*
Zju1876 edit step ladders
*/
# Include <stdio. h>
# Include <string. h>
# Define max (A, B) (a)> (B )? (A) (B ))
# Define n 25005
# Define l 20
Char a [n] [l];
Int f [N] = {0}, Max;
Char ch [] = {'Z', 'A', 'z '};
Int bsearch (char a [] [L], int N, char s []) {
Int L = 0, r = n-1, mid, K;
If (L> r) Return-1;
While (L <= r ){
Mid = (L + r)/2;
K = strcmp (A [Mid], S );
If (k = 0) return mid;
If (k> 0) r = mid-1;
If (k <0) L = Mid + 1;
}
Return-1;
}
Void add (char s [], int K, char CH, char T []) {
Int I;
For (I = 0; I <K; I ++) T [I] = s [I];
T [k] = CH;
For (I = K; s [I]; I ++) T [I + 1] = s [I];
T [I + 1] = '/0 ';
}
Void del (char s [], int K, char T []) {
Int I;
For (I = 0; I <K; I ++) T [I] = s [I];
For (I = k + 1; s [I]; I ++) T [I-1] = s [I];
T [I-1] = '/0 ';
}
Void change (char s [], int K, char CH, char T []) {
Int I;
For (I = 0; s [I]; I ++) T [I] = s [I];
T [k] = CH;
T [I] = '/0 ';
}
Void edit (int e, char s [], int K, char CH, char T []) {
If (E = 0) add (S, K, CH, t );
If (E = 1) del (S, K, t );
If (E = 2) Change (S, K, CH, t );
}
Int main ()
{
Int I, J, K, M, N = 0, E;
Char s [L], ch;
// Input
While (scanf ("% s", a [n])! = EOF) n ++;
// DP
F [0] = 1; max = 1; C [0] = 1;
For (I = 1; I <n; I ++ ){
F [I] = 1;
// Edit words
For (E = 0; e <3; E ++) {// 0: Add 1: del 2: Change
For (k = 0; A [I] [k]; k ++ ){
For (CH = 'a'; ch <= CH [E]; ch ++ ){
Edit (E, a [I], K, CH, S );
If (strcmp (s, A [I])> = 0) break;
J = bsearch (A, I, S );
If (j> = 0 & F [I] <F [J] + 1 ){
F [I] = f [J] + 1;
If (max <F [I]) max = f [I];
}
}
}
}
}
// Output
Printf ("% d/N", max );
Return 0;
}