Editorialul problemei Cuvinte5

Enunt:

Costul pentru a transforma un cuvant in altul este distanta levenstein2 dintre cele doua cuvinte. Cate este costul minim de-a ajunge din A in B trecand prin K alte cuvinte dintr-un dictionar?

Subtask1:

Cuvintele din query fac parte din dictionar.
Pentru a calcula distanta dintre doua cuvinte, ne putem defini functia

Dist(A, B) = distanta levenstein2

Functia Dist este o dinamica simpla in O(lungime2).
Daca aveti neclaritati uitati-va pe articolul de pe Wikipedia (distanta levenstein este un concept foarte des intalnit care merita aprofundat).

Ne definim dinamica
dp[i][j][l] ca fiind costul minim de-a ajunge de la al i-lea cuvant la al j-lea cuvant trecand prim maxim l schimbari.

Recurenta poate fi calculata usor in O(n4):
dp[i][j]1 = Dist(cuvant[i], cuvant[j]). Altfel spus, costul de-a ajunge de la al i-lea cuvant la al j-lea cuvant intr-un pas este din definitie Dist(al i-lea cuvant si al j-lea cuvant).

dp[i][j][l] unde l > 1 poate veni fie din dp[i][j][l - 1] daca decidem ca nu avem nevoie de a l-a mutare, fie din dp[i][q][l - 1] + dp[q][j]1, unde 1 <= q <= n. Altfel spus, pentru a ajunge de la al i-lea cuvant la al j-lea cuvant in l mutari, trebuie sa facem o 'escala' la a (l-1)-a mutare, pe care putem sa o iteram.

Raspunsul pentru un Query este dp[id-ul lui A][id-ul lui B][K].

Complexitate:
O(N2 * L2 + N4 + Q * N)

Subtask2:

Cum K = N + 1 pentru toate cazurile, observam ca dinamica de la Subtaskul 1 poate fi transformata in dp[i][j] = cost minim de la i la j, care poate fi calculata in O(n3).

Rezolvarea subtaskurilor se rezolva ca la ultimul Subtask.

Complexitate:
O(N2 * L2 + N3 + Q * (N2 + N * L2))

Subtask3:

Numarul de Queryuri este foarte mic.
Pentru fiecare Query, ne putem varia cuvantul din dictionar in care intram, si cuvantul din dictionar din care o sa iesim.
Apar cateva cazuri:

  1. K = 1 => raspunsul este Dist(A, B).
  2. K = 2 => raspunsul este min(cazul 1, Dist(A, X) + Dist(X, B)), unde X este un cuvant din dictionar.
  3. K > 2 => raspunsul este min(cazul 1, Dist(A, X) + dp[X][Y][K - 2] + Dist(Y, B)), unde X si Y sunt cuvinte din dictionar.

Complexitate:
O(N2 * L2 + N4 + Q * (N2 * L2))

Subtask4:

Solutia este similara cu Subtaskul 3, doar ca pentru fiecare Query ne precalculam Dist(A, X) si Dist(X, B) pentru totate cuvintele X din dictionar.

Complexitate:
O(N2 * L2 + N4 + Q * (N * L2 + N2))
Factorul de N2 * L2 vine din precalcularea distantei dintre oricare doua cuvinte din dictionar.
Factorul de N4 vine din calcularea dinamici dp[i][j][l].
Factorul de Q * N * L2 vine din calcularea distantei dintre cuvintele din query si cele din dictionar.
Factorul de Q * N2 vine din calcularea intrarii si iesirii din dinamica (cazurile din subtasul 3).