Task 93. Очередь за билетами

Task 93. Очередь за билетами

UniLecs

Задача: За билетами в кино выстроилась очередь из N человек. Кассир продает не более 3х билетов в одни руки. Известно, что на продажу i-му человеку из очереди 1го билета кассир тратит Ai секунд, на продажу 2х билетов - Bi секунд, 3х билетов - Ci секунд. 

Необходимо выяснить минимальное время, за ктр все покупатели могли бы приобрести билеты.

P.S. Билеты на "группу" людей всегда покупает только первый из группы. Также никто в целях ускорения не покупает лишних билетов (т.е. билетов, ктр никому не нужны).

Входные данные: N - кол-во покупателей в очереди, N меньше 1000.

A, B, C - массивы натуральных чисел, ктр хранят значения времени продажи одного, двух и трех билетов i-му покпателю. Значения в массиве не превышают 1000.

Вывод: минимальное время, за ктр все покупатели смогут приобрести билеты.

Пример: N = 5;

A = [5, 2, 5, 20, 20]

B = [10, 10, 5, 20, 1]

C = [15, 15, 5, 1, 1]

MinTime = 12

Идея: воспользуемся методом динамического программирования:

заведем массив time, в time[i] будем хранить минимальное время, за ктр можно продать билеты от 1го покупателя до i-го. 

Разберем частные случаи:

  • Для одного покупателя очевидно, что time[1] = A[0]. Для удобства расчетов пусть time[0] = 0.
  • Два покпателя смогут взять билеты по отдельности, и тогда время будет A[0] + A[1]. (нумерация с 0). Либо они могут договориться и тогда первый покупатель возьмет два билета за B[0] сек. Получим формулу для 2х покупателей:

time[2] = Min(A[0] + A[1], B[0])

  • Для 3х и более покупателей получим обобщенную формулу:
time[i] = Min(time[i - 1] + A[i - 1], time[i - 2] + B[i - 2], time[i - 3] + C[i - 3])

Нумерация идет с 0, но для удобства расчетов мы положили, что time[0] = 0.

Реализация:

C#

https://gist.github.com/unilecs/57ab6fe46116a56697e39e7524525ef6

Test:

https://dotnetfiddle.net/CCfsUp

Задача с сайта: acmp.ru

Report Page