Разбор задачи: Сварливый владелец книжного магазина

Предложенный нами код:

 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)

Что здесь происходит:

  1. На каждой итерации добавляем новых клиентов из текущей минуты (i), если владелец раздражён (grumpy[i] == 1).
  2. Убираем из расчёта клиентов, которые находятся за пределами текущего окна из minutes минут (i - minutes).
  3. Сравниваем текущую выгоду 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

Шаги:

  1. Изначально довольные клиенты: 10.
  2. Максимальная выгода от использования техники: 6.
  3. Итог: 10 + 6 = 16.

Ответ: 16.

 


0

Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии