3. Динамично оптимиране - други задачи

План:
Задачи за домашно 1 и 2
Домино подредица
Разстояние на Левенщайн
Задачи за домашно 3 и 4


**Домино подредица [8.4.12, стр. 579]

Домино-редица ще наричаме редица от естествени числа, за която най-старшата цифра на i-тия член съвпада с най-младшата на (i–1)-ия.

Пример 1:
34 402 2 29 91 11 1

Задача: По зададена редица X(n)  x1, x2, ..., xn от естествени числа да се намери нейна максимална по дължина домино-подредица.

Пример 2:
 25 62 36 51 12 6 33 22
[1   2   3   4   5   6  7   8]

Да разгледаме редицата X(k)  xk, xk+1, ..., xn. С F(i, k) означаваме максималната дължина на домино-редица, подредица на X(k),  и с първа цифра i на първия член на домино-редицата.
i = 0, 1, 2, ...., 9; k = 1, 2, ..., n

Пример 2:

F(1, 8) = F(1, 7) = F(1, 6) = 0;  F(1, 5) = F(1, 4) = F(1, 3) = F(1, 2) = F(1, 1) = 2; 12 22
F(2, 8) = F(2, 7) = F(2, 6) =  F(2, 5) = F(2, 4) = F(2, 3) = F(2, 2) = 1, F(2, 1) = 4; 25 51 12 22
...
Решението на задачата ще бъде най-голямото от числата F(1, 1), F(2, 1), ..., F(9, 1).

Означаваме с l(k) първата цифра на числото xk и с r(k) - последната цифра на xk.

Рекурентните равенства са:

F(i, k) = F(i, k + 1), ако l(k) != i;
Ако първата цифра l(k) на xk е различна от i, xk не може да влияе на стойността на F(i, k).
F(i, k) = max{F(i, k + 1), 1 + F(r(k), k + 1)}, ако  l(k) = i;
Ако i = l(k), са налице две възможности — да игнорираме xk или да го вмъкнем като първи елемент на максималната домино-подредица с първи елемент, започващ с последната цифра на xk - r(k).

Пример 2:
F(1, 5) = max{F(1, 6), 1 + F(2, 6)} = 2
F(2, 1) = max{F(2, 2), 1 + F(5, 2)} = 4
Програмиране = ++Алгоритми; (Programming = ++Algorithms;)
** Разстояние на Левенщайн [Edit distance, AL p. 74]

Разстояние на Левенщайн между два низа е минималният брой операции за редактиране, необходими за преобразуване на низ в друг низ. Операциите за редактиране са:

• insert - добавя символ (например ABC -> ABCA)
• remove - изтрива символ (например ABC -> AC)
• modify - замества един символ с друг (например ABC -> ADC)

Например разстоянието между LOVE и MOVIE е 2, защото можем първо да извършим операцията LOVE -> MOVE (modify) и след това операцията MOVE -> MOVIE (insert).
Това е най-малкият възможен брой операции, защото е ясно, че само една операция не е достатъчна.

Нека са дадени низовете s1 и s2.
distance(a, b) е разстоянието между низовете s1.substr(0, a )  и  s2.substr(0, b)

distance(a, b) = min{distance(a, b −1) + 1,
                                 distance(a − 1, b) + 1,
                                 distance(a − 1, b − 1) + cost(a, b)}.
distance(0, b) = b; distance(a, 0)  = a;

cost(a, b) = 1, ако s1[a] != s2[b] и cost(a, b) = 0, ако s1[a] == s2[b].



L - 1
O - 2
V- 3
E - 4

0
1
2
3
4
M - 1
1
min{2, 2, 1} = 1
2
3
4
O -2
2
2
1
2
3
V - 3
3




I - 4
4




E - 5
5