На прямой дощечке вбиты гвоздики. Любые два гвоздика можно соединить ниточкой. Требуется соединить некоторые пары гвоздиков ниточками так, чтобы к каждому гвоздику была привязана хотя бы одна ниточка, а суммарная длина всех ниточек была минимальна.
Формат входных данных:
В первой строке входного файла записано число N - количество гвоздиков (1 <= N <= 100). В следующей строке записано N чисел - координаты всех гвоздиков (неотрицательные целые числа, не превосходящие 10000).
Формат выходных данных:
В выходной файл нужно вывести единственное число - минимальную суммарную длину всех ниточек.
НЕ ОЛИМПИАДА!
Другие языки программирования и технологии
написать программу на языке Pascal.
procedure bs(var a: array of integer; n: integer);
var
c, t: integer;
s: boolean;
begin
repeat
s := false;
for c := 0 to n - 2 do
if a[c] > a[c+1] then begin
t := a[c]; a[c] := a[c+1]; a[c+1] := t;
s := true
end;
dec(n);
until not s;
end;
function mn(x, y: longint): longint;
begin
if x < y then mn := x else mn := y;
end;
var
m: array [0..100] of longint;
function tl(var a: array of integer; n: integer): longint;
var
l: longint;
begin
if n <= 2 then
tl := a[2] - a[1]
else if n = 3 then
tl := a[3] - a[1]
else
if m[n] >= 0 then
tl := m[n]
else begin
l := mn(a[n] - a[n - 1] + tl(a, n - 1), a[n] - a[n - 1] + tl(a, n - 2));
m[n] := l;
tl := l;
end;
end;
var
n, j: integer;
c: array [0..100] of integer;
begin
assign(input, 'input.txt'); reset(input);
assign(output, 'output.txt'); rewrite(output);
readln(n);
for j := 1 to n do read(c[j]);
for j := 0 to n do m[j] := -1;
bs(c, n + 1);
write(tl(c, n));
end.
var
c, t: integer;
s: boolean;
begin
repeat
s := false;
for c := 0 to n - 2 do
if a[c] > a[c+1] then begin
t := a[c]; a[c] := a[c+1]; a[c+1] := t;
s := true
end;
dec(n);
until not s;
end;
function mn(x, y: longint): longint;
begin
if x < y then mn := x else mn := y;
end;
var
m: array [0..100] of longint;
function tl(var a: array of integer; n: integer): longint;
var
l: longint;
begin
if n <= 2 then
tl := a[2] - a[1]
else if n = 3 then
tl := a[3] - a[1]
else
if m[n] >= 0 then
tl := m[n]
else begin
l := mn(a[n] - a[n - 1] + tl(a, n - 1), a[n] - a[n - 1] + tl(a, n - 2));
m[n] := l;
tl := l;
end;
end;
var
n, j: integer;
c: array [0..100] of integer;
begin
assign(input, 'input.txt'); reset(input);
assign(output, 'output.txt'); rewrite(output);
readln(n);
for j := 1 to n do read(c[j]);
for j := 0 to n do m[j] := -1;
bs(c, n + 1);
write(tl(c, n));
end.
Однако только полным перебором можно решить данную задачу.
Проще, наверное, с помощью рекурсии и множества.
Получается примерно вот так:
N = 10
Точки: (8125,2912)(7050,6926)(2885,281)(5611,8517)(7259,9425)(240,4737)(1533,6385)(2678,406)(8876,1790)(713,7114)
11124.9707137598
N = 10
Точки: (531,4265)(1737,3189)(884,281)(6947,4549)(2969,5534)(6795,2735)(8423,1320)(5835,2065)(8363,3756)(5762,7129)
12225.5613063523
N = 12
Точки: (8195,8973)(1248,7546)(2526,3227)(7764,485)(3207,509)(4775,605)(9900,3396)(1606,3909)(4653,5916)(7504,7597)(7711,3280)(637,7492)
12517.2006499802
Для увеличения быстродействия, но с потерей памяти, можно загонять уже просчитанные длины для каждой пары координат в динамический список…
Но это уже в порядке улучшения алгоритма!
Проще, наверное, с помощью рекурсии и множества.
Получается примерно вот так:
N = 10
Точки: (8125,2912)(7050,6926)(2885,281)(5611,8517)(7259,9425)(240,4737)(1533,6385)(2678,406)(8876,1790)(713,7114)
11124.9707137598
N = 10
Точки: (531,4265)(1737,3189)(884,281)(6947,4549)(2969,5534)(6795,2735)(8423,1320)(5835,2065)(8363,3756)(5762,7129)
12225.5613063523
N = 12
Точки: (8195,8973)(1248,7546)(2526,3227)(7764,485)(3207,509)(4775,605)(9900,3396)(1606,3909)(4653,5916)(7504,7597)(7711,3280)(637,7492)
12517.2006499802
Для увеличения быстродействия, но с потерей памяти, можно загонять уже просчитанные длины для каждой пары координат в динамический список…
Но это уже в порядке улучшения алгоритма!
Ну и пиши на здоровье!
А за тебя на халяву никто писать не будет.
А за тебя на халяву никто писать не будет.
ДЛя неолимпиадной задачи как-то слишком надуманно. Плюс формат ввода-вывода указан.
А вот кстате ссылка на одну из олимпиад: http:// olympiads. ru/sng/2/description2.shtml
А вот кстате ссылка на одну из олимпиад: http:// olympiads. ru/sng/2/description2.shtml
Nurlan_Ts Ns_Ts
Задача 232 http://dist-olimpiada.krasnogorka.edusite.ru/p24aa1.html
Сначала отсортируем гвоздики по возрастанию координат. Решим следующую подзадачу: найдем минимальную длину веревочек, необходимую для того, чтобы связать первые k гвоздиков согласно условию (обозначим требующуюся для этого длину веревочек ak).
Можно считать, что любая ниточка связывает два соседних гвоздика (иначе ее можно разрезать на несколько частей, связывающих все гвоздики между теми, которые связывала наша ниточка изначально) .
Научимся вычислять ak. Заметим, что в оптимальной конфигурации (для первых k гвоздиков) между последним (k-м) и предпоследним ((k-1)-м) гвоздиками ниточка есть всегда, а вот между предпоследним ((k-1)-м) и предпредпоследним ((k-2)-м) она может либо быть, либо не быть. В первом случае первые k-1 гвоздиков удовлетворяют условию задачи, во втором - первые k-2. Значит ak=min(ak-1,ak-2)+lk-1,k, где lk-1,k - расстояние между k-м и k-1-м гвоздиками (в отсортированном массиве) . Для удобства вычислений удобно ввести фиктивные первый и нулевой элементы равные 0 и бесконечности соответственно (в реальной программе в роли бесконечности обычно выступает какое-нибудь достаточно большое число, например для данной задачи вполне подойдет 30000). Теперь последовательно заполняя массив a с помощью данной формулы, мы получим верный ответ на поставленную задачу в элементе aN.
Число действий, выполненных данным алгоритмом, пропорционально N.
Можно считать, что любая ниточка связывает два соседних гвоздика (иначе ее можно разрезать на несколько частей, связывающих все гвоздики между теми, которые связывала наша ниточка изначально) .
Научимся вычислять ak. Заметим, что в оптимальной конфигурации (для первых k гвоздиков) между последним (k-м) и предпоследним ((k-1)-м) гвоздиками ниточка есть всегда, а вот между предпоследним ((k-1)-м) и предпредпоследним ((k-2)-м) она может либо быть, либо не быть. В первом случае первые k-1 гвоздиков удовлетворяют условию задачи, во втором - первые k-2. Значит ak=min(ak-1,ak-2)+lk-1,k, где lk-1,k - расстояние между k-м и k-1-м гвоздиками (в отсортированном массиве) . Для удобства вычислений удобно ввести фиктивные первый и нулевой элементы равные 0 и бесконечности соответственно (в реальной программе в роли бесконечности обычно выступает какое-нибудь достаточно большое число, например для данной задачи вполне подойдет 30000). Теперь последовательно заполняя массив a с помощью данной формулы, мы получим верный ответ на поставленную задачу в элементе aN.
Число действий, выполненных данным алгоритмом, пропорционально N.
Похожие вопросы
- Помогите написать программу на языке Pascal ABC
- Информатика. Составить программу на языке Pascal
- Помогите написать 2 программы на языке pascal!
- помогите понять-программа, которая переводит новую написанную программу на языке, понятном прогр
- Помогите составить программу на языке Pascal
- Помогите составить программу на языке Pascal
- Напишите программу на языке Паскаль для решения задачи:
- Как написать программу в Turbo Pascal?
- Проверьте программу на языке Pascal
- Как можно составить программу на языке Pascal для вычисления 100!-2 в степени 100?