
Problem Statement
In this problem, we are tasked with painting a row of n
houses, with a requirement that no two adjacent houses can be painted the same color. There are three possible colors to choose from—red, blue, or green—and each color has a different associated cost for each house. These costs are given in an n x 3
matrix named costs
, where each row corresponds to a house and the entries in each row represent the cost of painting that house red, blue, or green, respectively.
The challenge is to determine the minimum cost required to paint all the houses meeting the above criteria. Each element in the matrix costs[i][j]
stands for the cost of painting the i-th
house with the j-th
color where j
corresponds to red, blue, and green colors.
Examples
Example 1
Input:
costs = [[17,2,17],[16,16,5],[14,3,19]]
Output:
10
Explanation:
Paint house 0 into blue, paint house 1 into green, paint house 2 into blue. Minimum cost: 2 + 5 + 3 = 10.
Example 2
Input:
costs = [[7,6,2]]
Output:
2
Constraints
costs.length == n
costs[i].length == 3
1 <= n <= 100
1 <= costs[i][j] <= 20
Approach and Intuition
Given the restrictions and requirements of the problem, the naive approach would be extremely inefficient. We need a strategy that efficiently finds the minimum cost without redundantly recalculating for every possible scenario. Here is an intuitive approach to solve the problem using dynamic programming:
Initialization:
- Start by creating a matrix (
dp
) that will store the minimum painting costs.dp[i][c]
will represent the minimum cost to paint up to thei-th
house, where thei-th
house is painted with colorc
.
- Start by creating a matrix (
Base Case:
- Initialize the first row of
dp
with the same values as the first row ofcosts
because the first house can be painted independently with any of the three colors.
- Initialize the first row of
Fill the DP table:
- For each subsequent house (
i
from 1 ton-1
), calculate the cost of painting it with each of the three colors. Use the costs from the previous house to ensure no two adjacent houses are painted the same color. - For example, if deciding the cost of painting house
i
blue, you would take the minimum cost of painting the previous house either red or green, and add it to the cost of painting the current house blue. - Formally, for each color
c
for thei-th
house:pythondp[i][0] = costs[i][0] + min(dp[i-1][1], dp[i-1][2]) # Cost for painting i-th house RED dp[i][1] = costs[i][1] + min(dp[i-1][0], dp[i-1][2]) # Cost for painting i-th house BLUE dp[i][2] = costs[i][2] + min(dp[i-1][0], dp[i-1][1]) # Cost for painting i-th house GREEN
- For each subsequent house (
Compute the Result:
- After processing all houses, the last row of
dp
will contain the costs of painting all houses with each color fulfilling the problem's condition. The minimum of these values will be the result, which is the minimum cost to paint all houses such that no two adjacent houses have the same color.
- After processing all houses, the last row of
By adhering to these steps, the problem leverages overlapping subproblems (common in dynamic programming scenarios) efficiently by building up the solution for the whole row of houses based on the solutions of smaller inputs (previous houses). This approach ensures that the problem is solved in a time complexity of O(n), which is efficient given the provided constraints.
Solutions
- C++
- Java
class Solution {
public:
int calculateMinCost(vector<vector<int>>& expenses) {
if (expenses.empty()) return 0;
vector<int> lastRow = expenses.back();
for (int i = expenses.size() - 2; i >= 0; --i) {
vector<int> currentSpending = expenses[i];
currentSpending[0] += min(lastRow[1], lastRow[2]);
currentSpending[1] += min(lastRow[0], lastRow[2]);
currentSpending[2] += min(lastRow[0], lastRow[1]);
lastRow = currentSpending;
}
return min({lastRow[0], lastRow[1], lastRow[2]});
}
};
The provided C++ class, Solution
, includes a method named calculateMinCost
designed to solve the problem of minimizing the painting cost of a series of houses, where each house can be painted with one of three different colors, and each color incurs a specific expense. The constraints specify that no two adjacent houses can be painted the same color.
The method takes a 2D vector expenses
, where each row represents a house and the columns represent the cost of painting that house with one of the three colors. Here’s a breakdown of how the solution works:
- Begin by checking if the
expenses
vector is empty. If it is, return 0, as there are no expenses to consider. - Initialize
lastRow
to the last row of theexpenses
vector, which represents the base case for the last house. - Iterate over the expenses from the second-to-last row up to the first row:
- For each house (row), retrieve the current row’s expenses.
- Update the expense of painting the house with each color by adding the minimum of the feasible expenses of painting the next house (from
lastRow
) with the other two colors. This step ensures that no two adjacent houses will have the same color and seeks to find the minimum expense to the current point. - Update
lastRow
to be the current row’s modified expenses for use in the next iteration.
- After finishing the iteration for all houses, find the minimum expense from
lastRow
, which now contains the minimum accessible expenses for painting all houses up to that point. - Return the minimum value found, which provides the minimal cost of painting all the houses according to the given constraints.
Effectively, this code applies a dynamic programming approach that iteratively computes the minimal costs from the last house to the first, leveraging the computed results of subsequent houses to determine optimal solutions for preceding ones. This optimizes computation and adheres to the requirement of different colors for adjacent houses.
class Solution {
public int calculateMinimalCost(int[][] paintingCosts) {
if (paintingCosts.length == 0) return 0;
int[] lastRow = paintingCosts[paintingCosts.length - 1];
for (int i = paintingCosts.length - 2; i >= 0; i--) {
int[] current = paintingCosts[i];
current[0] += Math.min(lastRow[1], lastRow[2]);
current[1] += Math.min(lastRow[0], lastRow[2]);
current[2] += Math.min(lastRow[0], lastRow[1]);
lastRow = current;
}
return Math.min(
Math.min(lastRow[0], lastRow[1]),
lastRow[2]
);
}
}
The provided Java solution addresses the "Paint House" problem, where the goal is to find the minimum painting cost for a row of houses such that no two adjacent houses have the same color. The solution uses dynamic programming to efficiently compute the minimal cost.
- Input: A 2D integer array
paintingCosts
, wherepaintingCosts[i][j]
represents the cost of painting the i-th house with color j. - Output: The method
calculateMinimalCost
returns the minimal cost of painting all houses under the given constraints.
Working:
- First, check if the input array is empty. If empty, return
0
since no cost is associated with painting zero houses. - Initialize
lastRow
to hold the painting costs of the last row (or the last house) in the input array. - Iterate backwards through the array starting from the second-last row:
- For each house (
current
), update its painting cost for each color by adding the minimum cost of painting the next house with the other two colors. This ensures no two adjacent houses are painted the same color. - Update
lastRow
to thecurrent
to use it for the next iteration in computing costs for the house before it.
- For each house (
- After processing all rows (houses), determine the minimum cost from the first row of the array, which now contains the accumulative cost of painting all subsequent houses.
- Return the minimum value among the three color options for the first house.
This method efficiently calculates the minimum painting cost using a bottom-up approach, ensuring each house is considered with optimal previous choices.
No comments yet.