Однажды N путешественников решили ночью пересечь по веревочному мосту быструю горную речку. Без освещения перейти мост невозможно. К счастью, у одного из них оказался с собой фонарик. Известно, что мост выдерживает только двоих, а скорости людей могут различаться. Если мост пересекают два человека с разной скоростью, то они вынуждены двигаться со скоростью самого медленного из них. Скорость движения каждого из путников известна. Помогите путешественникам как можно быстрее перебраться через мост. Требуется написать программу, определяющую минимальное время, которое потребуется для такого перехода. Например, если N=4, а время, требуемое для перехода по мосту для каждого, составляет 5, 10, 20 и 25 минут соответственно, то наименьшее время, требуемое для пересечения моста, составит ровно 60 минут. Входные данныеВ первой строке входного файла INPUT.TXT содержится натуральное число N – количество путешественников (N <= 105). Во второй строке располагаются N натуральных чисел – скорости всех путников, разделенные пробелом и не превосходящие 106. Здесь под скоростью человека понимается время в минутах, необходимое для перехода через мост. Выходные данныеВ выходной файл OUTPUT.TXT выведите одно целое число – минимально возможное время, необходимое путникам для пересечения моста. Примеры№INPUT.TXTOUTPUT.TXT12
10 202024
5 10 20 2560
Другие языки программирования и технологии
Задача по рекурсивному программированию (Паскаль)
> самый быстрый и первый попавшийся переходят на другой берег, затем самый быстрый забирает фонарик и возвращается за следующим.
Проверим (здесь чХ -- обозначает человека, переходящего мост за Х минут) :
ч5 и ч10 переправляются на противоположный берег, проходит 10 минут
ч5 возвращается обратно, проходит 5 минут
ч5 и ч20 туда -- 20 минут
ч5 обратно -- 5 минут
ч5 и ч25 -- 25 минут
Итог: 65 минут
Оптимальный алгоритм:
ч5 и ч10 туда -- 10 минут
ч5 обратно -- 5 минут
ч20 и ч25 туда -- 25 минут
ч10 обратно -- 10 минут
ч5 и ч10 туда -- 10 минут
Итог: 60 минут
Из этого выходит оптимальный рекурсивный алгоритм, мы имеем три варианта:
1) Участников меньше трех и они имеют фонарь -- тривиально, они переправятся сразу;
2) Переправляется самый быстрый и самый медленный участники, самый быстрый возвращается обратно (это похоже на то, что предложили ответчики выше) ;
3) Переправляются 2 самых быстрых участника, один из них возвращается обратно, далее переправляются два самых медленных, и возвращается второй самый быстрый.
Каждый этап рекурсии на тот берег переправится либо один из самых медленных, либо двое самых медленных.
Реализация на С++:
#include <fstream>
#include <algorithm>
using namespace std;
int a[100001];
int f(int n) {
return n < 3? a[n] : min(a[1] + a[n] + f(n - 1), a[1] + 2 * a[2] + a[n] + f(n - 2));
}
int main() {
ifstream in("input.txt");
ofstream out("output.txt");
in >> a[0];
for (int i = 1; i <= a[0]; ++i) in >> a[i];
sort(&a[1], &a[1] + a[0]);
out << f(a[0]) << endl;
}
При желании код можно легко перевести в паскаль.
Проверим (здесь чХ -- обозначает человека, переходящего мост за Х минут) :
ч5 и ч10 переправляются на противоположный берег, проходит 10 минут
ч5 возвращается обратно, проходит 5 минут
ч5 и ч20 туда -- 20 минут
ч5 обратно -- 5 минут
ч5 и ч25 -- 25 минут
Итог: 65 минут
Оптимальный алгоритм:
ч5 и ч10 туда -- 10 минут
ч5 обратно -- 5 минут
ч20 и ч25 туда -- 25 минут
ч10 обратно -- 10 минут
ч5 и ч10 туда -- 10 минут
Итог: 60 минут
Из этого выходит оптимальный рекурсивный алгоритм, мы имеем три варианта:
1) Участников меньше трех и они имеют фонарь -- тривиально, они переправятся сразу;
2) Переправляется самый быстрый и самый медленный участники, самый быстрый возвращается обратно (это похоже на то, что предложили ответчики выше) ;
3) Переправляются 2 самых быстрых участника, один из них возвращается обратно, далее переправляются два самых медленных, и возвращается второй самый быстрый.
Каждый этап рекурсии на тот берег переправится либо один из самых медленных, либо двое самых медленных.
Реализация на С++:
#include <fstream>
#include <algorithm>
using namespace std;
int a[100001];
int f(int n) {
return n < 3? a[n] : min(a[1] + a[n] + f(n - 1), a[1] + 2 * a[2] + a[n] + f(n - 2));
}
int main() {
ifstream in("input.txt");
ofstream out("output.txt");
in >> a[0];
for (int i = 1; i <= a[0]; ++i) in >> a[i];
sort(&a[1], &a[1] + a[0]);
out << f(a[0]) << endl;
}
При желании код можно легко перевести в паскаль.
Что-то не так в условии.
При данных 5, 10, 20, 25 не получается 60…
65 не меньше!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для решения рекурсия не нужна:
1) Находим самое маленькое значение min
2) Остальные значения просто складываем и добавляем значение
min*(N-2) — сколько раз самый быстрый должен вернуться на исходный берег
При данных 5, 10, 20, 25 не получается 60…
65 не меньше!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для решения рекурсия не нужна:
1) Находим самое маленькое значение min
2) Остальные значения просто складываем и добавляем значение
min*(N-2) — сколько раз самый быстрый должен вернуться на исходный берег
Сначала нужно понять самый быстрый алгоритм движения, он прост: самый быстрый и первый попавшийся переходят на другой берег, затем самый быстрый забирает фонарик и возвращается за следующим. Так будет продолжаться, пока не люди не закончатся.
Сразу отмечу, если людей 1 или 2, то они просто переправятся и алгоритм не будет работать
Рекурсия действительно не нужна.
Но всё будет не так просто, как предлагал предыдущий автор. Его формула работает при числе людей, больших 1.
Но если есть желание/необходимость решать рекурсивно, могу предложить:
1. в процессе чтения из файла времен движения выбрать минимальное, запомнить все остальные в массив, не помещая туда время найденного (если самых быстрых несколько, в массив заносятся все, кроме одного)
2. напишем функцию, которая вернет время движения всех, начиная с индекса А. Функция будет получать индекс А и время самого быстрого К. Если осталось перевести только одного человека - то вернем его время, и прекратим рекурсию. Если людей больше, возьмём время с индексом А (оба идут туда) добавим к нему К (один возвращается) и добавим вызов функции с индексом А+1 и временем быстрого К (перейдём к следующему) .
3. в файл и на экран выводим результат вызова функции с индексом 1 и временем К.
Чтение из файла и вывод значения в файл нужно проверить ДО реализации алгоритма
Сразу отмечу, если людей 1 или 2, то они просто переправятся и алгоритм не будет работать
Рекурсия действительно не нужна.
Но всё будет не так просто, как предлагал предыдущий автор. Его формула работает при числе людей, больших 1.
Но если есть желание/необходимость решать рекурсивно, могу предложить:
1. в процессе чтения из файла времен движения выбрать минимальное, запомнить все остальные в массив, не помещая туда время найденного (если самых быстрых несколько, в массив заносятся все, кроме одного)
2. напишем функцию, которая вернет время движения всех, начиная с индекса А. Функция будет получать индекс А и время самого быстрого К. Если осталось перевести только одного человека - то вернем его время, и прекратим рекурсию. Если людей больше, возьмём время с индексом А (оба идут туда) добавим к нему К (один возвращается) и добавим вызов функции с индексом А+1 и временем быстрого К (перейдём к следующему) .
3. в файл и на экран выводим результат вызова функции с индексом 1 и временем К.
Чтение из файла и вывод значения в файл нужно проверить ДО реализации алгоритма
Похожие вопросы
- Программирование, паскаль
- Помогите решить задачу по информатике. Массивы. Язык программирования Паскаль.
- Программирование!!! Совсем не идет эта задача, нужно написать на паскале!!
- Стоит ли учить язык программирования: Паскаль
- Кто поможет в программировании?Паскаль
- Для чего нужен язык программирования паскаль?
- Язык программирования Паскаль
- Подскажите сайт где можно обучиться языку программирования "паскаль"?
- помогите решить плз! Программирование, Паскаль. Множества. прозьба без наворотов... Циклы, иф, подпрограммы, строки, множе
- Стоит следующая задача, нужно освоить программирование