UniLecs #Task. Robber

Albert Davletov
UniLecs
Published in
Nov 15, 2020

Задача: грабитель, планирует обчистить дома на улице. В каждом доме на этой улице спрятана определенная сумма денег. Все дома на этой улице расположены по кругу, т.е. 1й дом является соседом последнего.

Также в соседних домах есть сигнализация, и она автоматически сработает, если в одну ночь взломают два соседним дома.

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

Входные данные: arr — сумма положительных целых чисел, представляющих сумму денег в iм доме.

Вывод: profit — максимально возможный улов грабителя без срабатывания сигнализации.

Примеры:

  1. arr = [2, 3, 2]
    Output: 3 (нельзя ограбить 1й и 3й дом, т.к. они также являются соседними из-за круговой улицы).
  2. arr = [1,2,3,1]
    Output: 4 (грабим 1й и 3й дом)

Разбор

Заметим, что для прямой улицы есть нектр закономерность для простых случаев:

  1. Один дом на улице, то ответ — стоимость этого дома.
  2. Два дома, то ответ — это Max(house1, house2).
  3. Три дома, то можно выбрать средний дом или сумму первого и последнего домов. То есть Max(house3 + house1, house2).

Отсюда можно вывести общую формулу для метода динамического программирования: dp[i] = Max(dp[i — 1], dp[i — 2] + nums[i]).

Также следует учесть, что улица круговая. Это значит, что отсчет мы можем начать либо с 1го дома и тогда последний дом не будет включен в подсчет. Либо начать отсчет со 2го дома и тогда последний дом будет включен в подсчет. То есть отдельно подсчитаем оба варианта и выберем оптимальный. Детали реализации смотрите в коде.

Реализация

C#

https://gist.github.com/unilecs/c3300573943dc0ada0937c2f4ff6b607

Play-test

https://dotnetfiddle.net/SXbIVJ

--

--