Будемо моделювати процес продажу квитків за допомогою мультимножини . Спочатку підведемо до вільних кас перших людей і занесемо час їх обслуговування в мультимножину.
У процесі роботи мультимножина завжди міститиме елементів, кожен з яких позначає момент часу, коли відповідна каса звільниться і зможе прийняти наступного клієнта. Очевидно, що кожна нова людина повинна підходити до тієї каси, для якої цей момент мінімальний.
Час обслуговування останнього клієнта і буде шуканим значенням.
Приклад
Розглянемо наведений приклад. Спочатку додаємо в купу перші k = 3 елементи.
Далі на кожній ітерації беремо наступний елемент (наступну людину з черги) і ставимо його замість найменшого — у ту чергу, яка звільниться раніше. У чергу додаємо час, коли ця нова людина завершить обслуговування на касі.
Поруч з кожним малюнком вказані числа, що знаходяться в купі.
Реалізація алгоритму
Інформацію про моменти часу, коли відбувається продаж квитків у касах, зберігаємо в мультимножині .
multiset<long long> s;Зчитуємо вхідні дані. Час обслуговування перших людей заносимо в .
scanf("%d %d",&n,&k);
for(i = 0; i < n; i++)
{
scanf("%d",&ti);
if (s.size() != k) s.insert(ti);
else
{Знаходимо людину, яка завершить обслуговування раніше за всіх, і ставимо за нею наступну з черги.
long long temp = *s.begin();
s.erase(s.begin());
s.insert(temp + ti);
}
}Найбільше число в мультимножині — це момент часу, коли буде обслуговано останнього клієнта. Воно і є шуканим значенням.
while(s.size() > 1) s.erase(s.begin());
printf("%lld\n",*s.begin());Реалізація алгоритму — черга з пріоритетами
Створимо купу, у вершині якої буде знаходитися найменший елемент.
priority_queue<long long, vector<long long>, greater<long long> > pq;Зчитуємо вхідні дані. Час обслуговування перших людей заносимо в чергу .
scanf("%d %d",&n,&k);
for(i = 0; i < n; i++)
{
scanf("%d",&ti);
if (pq.size() != k) pq.push(ti);
else
{Знаходимо людину, яка завершить обслуговування раніше за всіх, і ставимо за нею наступну з черги.
long long temp = pq.top(); pq.pop();
pq.push(temp + ti);
}
}Найбільше число в черзі — це момент часу, коли буде обслуговано останнього клієнта. Воно і є шуканим значенням.
while(pq.size() > 1) pq.pop();
printf("%lld\n",pq.top());Java реалізація
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
int n = con.nextInt();
int k = con.nextInt();
PriorityQueue<Long> pq = new PriorityQueue<Long>();
for(int i = 0; i < n; i++)
{
long ti = con.nextLong();
if (pq.size() != k) pq.add(ti);
else pq.add(pq.poll() + ti);
}
while(pq.size() > 1) pq.poll();
System.out.println(pq.poll());
}
}