Автор Екатерина Мышьянова задал вопрос в разделе Другие языки и технологии
написать программу на языке Pascal. и получил лучший ответ
Ответ от Ra[гуру]
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.
Ну и пиши на здоровье!
А за тебя на халяву никто писать не будет.
Сначала отсортируем гвоздики по возрастанию координат. Решим следующую подзадачу: найдем минимальную длину веревочек, необходимую для того, чтобы связать первые 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.
Однако только полным перебором можно решить данную задачу.
Проще, наверное, с помощью рекурсии и множества.
Получается примерно вот так:
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