Матч 46, Сбор пищи (FoodCollecting)

Вам необходимо собрать neededFood единиц еды для солдат. Изначально имеется n работников. Каждый работник за один раунд собирает одну единицу еды. После каждого раунда Вы можете за еду нанимать новых работников. Каждый новый работник стоит price единиц еды. Необходимо вычислить наименьшее число раундов, за которое Вы соберете как минимум neededFood единиц еды.

Класс: FoodCollecting

Метод: int gather(int neededFood, int n, int price)

Ограничения: 1 £ neededFood, n, price £ 1000.

Вход. Количество еды neededFood, которое требуется собрать, изначальное число работников n и цена найма работника price.

Выход. Наименьшее число раундов, за которое можно собрать как минимум neededFood единиц еды.

Пример входа

neededFood

n

price

10

2

1

22

4

1

60

5

6

Пример выхода

4

4

11

РЕШЕНИЕ

жадный алгоритм

Поскольку количество собираемой еды neededFood не более 1000, то нам всегда будет достаточно не более neededFood работников. Предположим, что мы закончим сбор еды имея  n + x работников (0 £ n + x £ neededFood). Тогда работников следует набирать как можно быстрее, то есть вся собираемая еда в начальные раунды идет на найм. Когда мы наймем n + x работников, то далее только они будут собирать еду все оставшиеся раунды. Перебираем все допустимые значения x, для каждого из них находим наименьшее количество раундов, за которое будут собраны neededFood единиц еды. Параллельно подсчитываем минимальное значение среди всех найденных значений раундов для каждого x.

ПРОГРАММА

#include <stdio.h>

class FoodCollecting

{

public:

int gather(int neededFood, int n, int price)

{

int EWorkers,workers,food,days,best = 2000000000;

if (n >= neededFood) return 1;

for(EWorkers = n; EWorkers <= neededFood; EWorkers++)

{

food = days = 0; workers = n;

while(food < neededFood)

{

food += workers;

while((workers < EWorkers) && (food >= price))

workers++, food -= price;

days++;

}

if (days < best) best = days;

}

return best;

}

};