Hướng dẫn giải của kmpfriendly


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Ta tính KMP automaton ~aut~ của xâu ~s~ trước. Sau đó, công thức DP của chúng ta là ~\text{dp}[i][j][length] = dp[i + 1][j][\text{advance}(length, a[i + 1][j])] + dp[i][j + 1][\text{advance}(length, a[i][j + 1])]~. Hàm ~\text{advance}~ được định nghĩa như sau: ~\text{advance}(length, character) = aut[length][character]~ nếu ~length < |s|~, và ~\text{advance}(|s|, character) = |s|~. Kết quả cần tìm là ~\text{dp}[0][0][\text{advance}(0, a[0][0])]~.

Nếu ta loại trường hợp ~|s| \geq n + m~ thì ta có thể cài đặt KMP automaton trong ~O(|s|^2)~ bằng cách brute force. Lí do: khi ~|s| \geq n + m~ thì số đường đi bằng ~0~, ngược lại ta có thể chứng minh ~|s| \leq 1000~.

Việc chứng minh ~|s| \leq 1000~ là một việc yêu cầu trình độ toán cao. Tuy nhiên ta có thể dễ dàng chứng minh ~|s| \leq 1999~. Lời giải: nếu ~|s| \leq 1000~ ta suy ra ngay ~|s| \leq 1999~, ngược lại ta có ~|s| > 1000 \Rightarrow nm \leq 1000~. Từ đây ta có ~n \leq 1000~ và ~m \leq 1000~, suy ra ~|s| \leq n + m - 1 \leq 1000 + 1000 - 1 = 1999~.

Nếu ta không xét hai trường hợp riêng ra, ta vẫn có thể tính KMP automaton trong ~O(|s|)~ bằng thuật toán KMP.

Định nghĩa KMP automaton: với một xâu ~pattern~, ~aut[length][character]~ là độ dài tiền tố lớn nhất của ~pattern~ sao cho tiền tố đó là hậu tố của ~length~ kí tự đầu của ~pattern~ cộng với ~character~. Đọc thêm tại https://cp-algorithms.com/string/prefix-function.html#building-an-automaton-according-to-the-prefix-function.


Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.