- •Глава 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.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;