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
|
|
|
|
|