- •Глава 2. Перебор и методы его сокращения
- •2.1. Перебор с возвратом
- •2.1.1. Общая схема
- •2.1.2. Задача о расстановке ферзей
- •2.1.3. Задача о шахматном коне
- •2.1.4. Задача о лабиринте
- •2.1.5. Задача о парламенте
- •2.1.6. Задача о рюкзаке (перебор вариантов)
- •2.1.7. Задача о коммивояжере (перебор вариантов)
- •2.1.8. Задача о секторах
- •Входные и выходные данные
- •2.2. Динамическое программирование
- •2.2.1. Задача о Черепашке
- •2.2.2. Треугольник
- •2.2.3 Степень числа
- •2.2.4. Автозаправка
- •2.2.5. Алгоритм Нудельмана-Вунша
- •2.2.6. Разбиение выпуклого n-угольника
- •2.2.7. Задача о рюкзаке (динамическая схема)
- •2.2.8. Задача о паркете
- •2.2.9. «Канадские авиалинии»
- •2.3. Метод «решета»
- •2.3.1. Решето Эратосфена
- •2.3.2. Быки и коровы
- •2.4. Задачи
2.2.5. Алгоритм Нудельмана-Вунша
Пример из молекулярной биологии. Молекулы ДНК, содержащие генетическую информацию - это длинные слова из четырех букв (А, Г, Ц, Т). В процессе эволюции, в результате мутаций, последовательности меняются, одна буква может замениться на другую, выпасть, а может добавиться новая. Насколько похожи два фрагмента, каким наименьшим числом превращений можно один из них получить из другого? Формулировка задачи. Даны два слова (длины M и N), состоящие из букв А, Г, Ц, Т. Найти подпоследовательность наибольшей длины, входящую в то и другое слово.
Пример.
Слова ГЦАТАГГТЦ и АГЦААТГГТ. Схема
решения иллюстрируется следующим
рисунком.
На рисунке закрашены клетки, в строке и в столбце которых находятся одинаковые буквы. Принцип заполнения таблицы W следующий: элемент W[i,j] равен наибольшему из чисел W[i-1,j], W[i,j-1], а если клетка <i,j> закрашена, то и W[i-1,j-1]+1. Формирование первой строки и первого столбца выполняется до заполнения таблицы и осуществляется так: единицей отмечается первое совпадение, затем эта единица автоматически заносится во все оставшиеся клетки. Например, W[3,1] - первое совпадение в столбце, затем эта единица идет по первому столбцу. Подпоследовательность формируется при обратном просмотре заполненной таблицы от клетки, помеченной максимальным значением. Путь - это клетки с метками, отличающимися на единицу, буквы из закрашенных клеток выписываются. Последовательность этих букв - ответ задачи. Для нашего примера две подпоследовательности: ГЦААГГТ и ГЦАТГГТ.
Фрагмент основной логики.
...
for i:=1 to Length(S1) do
for j:=1 to Length(S2) do begin
A[i,j]:=Max(A[i-1,j],A[i,j-1]);
if S1[i]=S2[j] then A[i,j]:=Max(A[i,j],A[i-1,j-1]+1);
end;
Writeln(‘Ответ:’,A[Length(S1),Length(S2)]);
....
2.2.6. Разбиение выпуклого n-угольника
Дан выпуклый N-угольник, заданный координатами своих вершин в порядке обхода. Он разрезается N-2 диагоналями на треугольники. Стоимость разрезания определяется суммой длин всех использованных диагоналей. Найти разрез минимальной стоимости.
Идея решения разбирается с использованием следующего рисунка.

S[k,l]=min{длина диагонали <k,i>+длина диагонали <i,l>+S[k,i]+S[i,l]}. При этом следует учитывать, что при i=k+1 диагональ <k,i> является стороной многоугольника и ее длина считается равной нулю.
Пример(N=6).





2.2.7. Задача о рюкзаке (динамическая схема)
Рассмотрим задачу из пункта 1.1.6. Напомним ее формулировку. В рюкзак загружаются предметыnразличных типов (количество предметов каждого типа не ограничено). Максимальный вес рюкзака не превышаетW. Каждый предмет типаiимеет весwi и стоимостьvi (i=1,2, ..., n).Требуется определить максимальную стоимость груза, вес которого не превышаетW.Обозначим количество предметов типаiчерезki,тогда требуется максимизироватьv1*k1+v2*k2+...+vn*kn при ограниченияхw1*k1+w2*k2+...+wn*kn£W, где ki - целые(0£ki£[W/wi]), квадратные скобки означают целую часть числа.
Пусть вес рюкзака должен быть равен W.Формализуем задачу следующим образом.
Шаг i ставится в соответствие типу предметаi=1,2,...,n.
Состояние yi на шагеiвыражает суммарный вес предметов, решение о загрузке которых принято на шагах 0,1,...,i. При этомyn=W, yi=0,1,...,Wприi=1,2,...,n-1.
Варианты решения ki на шагеi описываются количеством предметов типаi, 0£ki£ëW/wiû.
Рассмотрим пример.W=6, и дано четыре предмета
|
i |
wi |
vi |
|
1 |
2 |
50 |
|
2 |
3 |
90 |
|
3 |
1 |
30 |
|
4 |
4 |
140 |

Схема работы для данного примера приведена на рисунке. В кружочках выделены только достижимые состояния (суммарные веса для каждого шага в соответствии с приведенной выше формализацией) на каждом шаге. В круглых скобках указаны стоимости соответствующих выборов, в квадратных скобках - максимальная стоимость данного заполнения рюкзака. «Жирными» линиями выделен способ наилучшей загрузки рюкзака.
Текст решения.
Const MaxN=???;
MaxK=???;
Type Thing=Record W,V:Word; end;
Var A:array[1..MaxN,0..MaxK] of word;
P:array[1..MaxN] of Thing;
Old,NewA:array[0..MaxK] of longint;
N,W:integer;
...
procedure Solve;
var k,i,j:integer;
begin
fillchar(Old,sizeof(Old),0);
for k:=1 to N do begin{цикл по шагам}
fillchar(NewA,sizeof(NewA),0);
for i:=0 to W do{цикл по состояниям шага}
for j:=0 to i div P[k].W do{цикл по вариантам решения - количеству предметов каждого вида}
if j*P[k].V+Old[i-j*P[k].W]>=NewA[i] then begin
NewA[i]:=j*P[k].V+Old[i-j*P[k].W];
A[k,i]:=j;{здесь j количество предметов?}
end;
Old:=NewA;
end;
end;
Вывод наилучшего решения.
procedure OutWay(k,l:integer);
begin
if k=0 then exit
else begin
OutWay(k-1,l-A[k,l]*P[k].V);{а здесь вес}
Write(A[k,l],’ ‘);
end;
end;

