Программа курса:
Разбор задачи: Сварливый владелец книжного магазина
Предложенный нами код:
def maxSatisfied(customers, grumpy, minutes):
"""
:param customers: List[int] - количество клиентов за каждую минуту
:param grumpy: List[int] - состояние владельца магазина (1 - раздражён, 0 - нет)
:param minutes: int - количество минут, в течение которых владелец может не раздражаться
:return: int - максимальное количество удовлетворённых клиентов
"""
# Удовлетворённые клиенты в минуты, когда владелец магазина не раздражён
satisfied_customers = sum(customers[i] for i in range(len(customers)) if grumpy[i] == 0)
# Подсчитываем возможную выгоду от использования техники на первых "minutes" минутах
additional_satisfied = sum(customers[i] for i in range(minutes) if grumpy[i] == 1)
max_additional = additional_satisfied
# Используем скользящее окно для подсчёта максимальной выгоды
for i in range(minutes, len(customers)):
if grumpy[i] == 1:
additional_satisfied += customers[i]
if grumpy[i - minutes] == 1:
additional_satisfied -= customers[i - minutes]
max_additional = max(max_additional, additional_satisfied)
return satisfied_customers + max_additional
Рассмотрим по шагам, как работает функция maxSatisfied. Цель задачи — максимизировать количество удовлетворённых клиентов, используя технику, позволяющую владельцу магазина не раздражаться в течение заданного количества минут.
1. Вычисление базового числа удовлетворённых клиентов
Первый шаг — это определить клиентов, которые изначально остались довольны, то есть тех, кто пришёл в минуты, когда владелец магазина не раздражался.
Фрагмент кода:
satisfied_customers = sum(customers[i] for i in range(len(customers)) if grumpy[i] == 0)
Что здесь происходит:
- Мы проходим по массиву
grumpyи проверяем, где значение равно0. - На этих позициях добавляем соответствующее значение из массива
customersк переменнойsatisfied_customers.
Пример: Если customers = [1, 0, 1, 2, 1, 1, 7, 5] и grumpy = [0, 1, 0, 1, 0, 1, 0, 1], то изначально довольны клиенты в минуты 0, 2, 4, и 6. Их суммарное количество:
1 (мин. 0) + 1 (мин. 2) + 1 (мин. 4) + 7 (мин. 6) = 10.
В результате satisfied_customers = 10.
2. Вычисление дополнительного числа удовлетворённых клиентов
Далее вычисляется потенциальная выгода от использования техники, позволяющей владельцу не раздражаться в течение minutes минут.
Фрагмент кода:
additional_satisfied = sum(customers[i] for i in range(minutes) if grumpy[i] == 1)
max_additional = additional_satisfied
Что здесь происходит:
- Мы рассматриваем первые
minutesминут и суммируем количество клиентов, которые остались бы довольны, если владелец перестанет раздражаться. - Эта сумма сохраняется в переменную
max_additional, так как она может быть максимальной на данном этапе.
Пример: Если minutes = 3, то для первых трёх минут (0, 1, 2) из массива grumpy только 1 и 2 имеют значение 1. Значит, добавляем:
0 (мин. 0) + 0 (мин. 1) + 1 (мин. 2) = 1.
3. Использование скользящего окна
Для оптимизации решения используется техника "скользящее окно". Мы проверяем, как изменяется число клиентов, которые могут остаться довольны, если технику применить к любому интервалу из minutes подряд идущих минут.
Фрагмент кода:
for i in range(minutes, len(customers)):
if grumpy[i] == 1:
additional_satisfied += customers[i]
if grumpy[i - minutes] == 1:
additional_satisfied -= customers[i - minutes]
max_additional = max(max_additional, additional_satisfied)
Что здесь происходит:
- На каждой итерации добавляем новых клиентов из текущей минуты (
i), если владелец раздражён (grumpy[i] == 1). - Убираем из расчёта клиентов, которые находятся за пределами текущего окна из
minutesминут (i - minutes). - Сравниваем текущую выгоду
additional_satisfiedс максимальной и обновляемmax_additional, если текущее значение больше.
Пример: Пусть customers = [1, 0, 1, 2, 1, 1, 7, 5], grumpy = [0, 1, 0, 1, 0, 1, 0, 1], minutes = 3.
На первом шаге интервал 0-2 (минуты 0, 1, 2):
- Выгода:
0 (мин. 0) + 0 (мин. 1) + 1 (мин. 2) = 1.
На следующем шаге интервал 1-3 (минуты 1, 2, 3):
- Добавляем клиентов из минуты
3:2. - Убираем клиентов из минуты
1:0. - Выгода:
1 (из прошлого окна) + 2 = 3.
На последующих шагах аналогично пересчитываются выгоды для всех интервалов.
4. Итоговый результат
После прохождения всех минут:
- Суммируем число изначально довольных клиентов (
satisfied_customers) и максимальную выгоду (max_additional). - Возвращаем результат.
Фрагмент кода:
return satisfied_customers + max_additional
Пример полного расчёта
Для входных данных:
customers = [1, 0, 1, 2, 1, 1, 7, 5]
grumpy = [0, 1, 0, 1, 0, 1, 0, 1]
minutes = 3
Шаги:
- Изначально довольные клиенты:
10. - Максимальная выгода от использования техники:
6. - Итог:
10 + 6 = 16.
Ответ: 16.