Эти проблемы в основном только за исключением ограничений. В первом вопросе к
всегда 3. Если мы решаем вторую проблему, то мы также можем решить первую проблему. Поэтому давайте подумаем о случае, когда к
не исправлено.
Дом краски (средний)
Дом краски (средний)
Существует ряд N домов, где каждый дом можно покрасить один из трех цветов: красный, синий или зеленый. Стоимость покраски каждого дома с определенным цветом отличается. Вы должны нарисовать все дома, так что ни одно двух соседних домов не имеют того же цвета.
Стоимость покраски каждого дома с определенным цветом представлена расходами затрат N X 3.
Например, затраты [0] [0] – стоимость живописи дома 0 с красным цветом; Стоимость [1] [2] – стоимость живописи дома 1 с зеленым цветом, и так далее … Верните минимальную стоимость нарисовать все дома.
Paint House II (жесткий)
Paint House II (жесткий)
Существует ряд N домов, каждый дом можно нарисовать одним из цветов k. Стоимость покраски каждого дома с определенным цветом отличается. Вы должны нарисовать все дома, так что ни одно двух соседних домов не имеют того же цвета.
Стоимость покраски каждого дома с определенным цветом представлена затратами N X K стоимости затрат.
Например, затраты [0] [0] – стоимость покрасочного дома 0 с цветом 0; Стоимость [1] [2] – стоимость живописи дома 1 с цветом 2, и так далее … Верните минимальную стоимость нарисовать все дома.
Решение 1: динамическое программирование
Предположим, мы получили 5 домов и 6 цветов (красный, зеленый, синий, желтый, фиолетовый, оранжевый).
Начиная со второго, мы можем выбрать только другой цвет из предыдущей строки. Например, если выбран расходы [1] [0], то только возможный цвет, который будет выбран из предыдущей строки, должен быть из столбца 1 к столбцу 5 и выбрать минимальные затраты [0] [J], где $ j \ neq 0 $ в этом примере.
Следовательно, мы повторяем каждый цвет в текущей строке и сравните его от предыдущей строки, чтобы найти минимальную стоимость. Следующее решение дает $ O (N * K ^ 2) Сложность времени в $ и $ O (K) $ Space Collectyity.
def minCostII(self, costs: List[List[int]]) -> int: n = len(costs) k = len(costs[0]) prev_row = costs[0] for house in range(1, n): cur_row = [0] * k for cur_color in range(k): prev_best = math.inf for prev_color in range(k): if cur_color == prev_color: continue prev_best = min(prev_best, prev_row[prev_color]) cur_row[cur_color] += prev_best + costs[house][cur_color] prev_row = cur_row return min(prev_row)
который можно написать более чистым способом.
def minCostII(self, costs: List[List[int]]) -> int: k = len(costs[0]) prev_row = [0] * k for cur_row in costs: prev_row = [cur_row[i] + min(prev_row[:i] + prev_row[i + 1:]) for i in range(k)] return min(prev_row)
Решение 2: Марковская цепь
Если n
и к
Установлены на 500 $, то решение 1 превысит ограничение по времени. Вот еще одно решение, использующее идею о цепочке Маркова. Учитывая, что к
Штаты (цвета) и n
Этапы, мы можем обновить матрицу, чтобы узнать оптимальное значение для каждого состояния на текущем этапе. Идея состоит в том, чтобы узнать первую и вторую минимальную стоимость для каждого этапа. Для следующего этапа мы можем обновить каждую стоимость, добавив либо первую минимальную стоимость или вторую. Причина, по которой нам нужны две минимальные затраты, так это то, что мы не можем нарисовать тот же цвет. Если индекс первой минимальной стоимости с предыдущего этапа – i
И мы должны использовать вторую минимальную стоимость текущего этапа и наоборот.
class Solution: def solve(self, matrix): n = len(matrix) k = len(matrix[0]) for house in range(1, n): first_mi_color = second_mi_color = None # find first & second min color for color in range(k): cost = matrix[house - 1][color] if first_mi_color is None or cost < matrix[house - 1][first_mi_color]: second_mi_color = first_mi_color first_mi_color = color elif second_mi_color is None or cost < matrix[house - 1][second_mi_color]: second_mi_color = color # update matrix for the current row for color in range(k): if color == first_mi_color: matrix[house][color] += matrix[house - 1][second_mi_color] else: matrix[house][color] += matrix[house - 1][first_mi_color] return min(matrix[-1])
Вот более короткая версия.
class Solution: def minCostII(self, costs: List[List[int]]) -> int: n, k = len(costs), len(costs[0]) for house in range(1, n): first_mi_cost = min(costs[house - 1]) idx = costs[house - 1].index(first_mi_cost) second_mi_cost = min(costs[house - 1][:idx] + costs[house - 1][idx + 1:]) for color in range(k): if color == idx: costs[house][color] += second_mi_cost else: costs[house][color] += first_mi_cost return min(costs[-1])
Оригинал: “https://dev.to/wingkwong/leetcode-paint-house-1eab”