Problem Statement
Paint House
You have a row of houses. Each house must be painted one of three colors: red, blue, or green. Painting a house a certain color costs a certain amount, and the cost is different for every house and color. There is one rule: two houses next to each other cannot be the same color. You are given a grid called costs, where costs[i][j] is the price to paint house i with color j. Your job is to paint every house while spending as little money as possible. The trick is that the best color for one house depends on what color you picked for the house right before it, so we will build up the answer house by house.
Signals to notice
Brute force first
Try all color assignments. Each house has k choices, exponential total. That direct path helps you understand the question, but it tends to treat every possibility as brand new instead of learning from earlier steps.
The key insight
DP: dp[i][c] = min cost to paint houses 0.i where house i is color c. dp[i][c] = cost[i][c] + min(dp[i-1][not c]). For 3 colors, just check the other two., optimizable to by tracking the two smallest. The goal is not to be clever for its own sake, but to remember the one relationship that keeps the solution grounded as you move forward.
Trace it on costs=[[17,2,17],[16,16,5],[14,3,19]]
init house0: r=17, g=2, b=17 house1 r = 16+min(g,b)=16+min(2,17)=18 house1 g = 16+min(r,b)=16+min(17,17)=33 house1 b = 5+min(r,g)=5+min(17,2)=7 -> r,g,b=18,33,7 house2 r = 14+min(g,b)=14+min(33,7)=21 house2 g = 3+min(r,b)=3+min(18,7)=10 house2 b = 19+min(r,g)=19+min(18,33)=37 -> r,g,b=21,10,37 answer = min(21,10,37) = 10
What must stay true
The optimal color for house i depends only on which color was cheapest for house i-1 EXCLUDING the same color. Tracking the two cheapest previous costs lets you decide in per color. If that remains true after every update, the rest of the reasoning has a stable place to stand.
Shape of the loop
r, g, b = costs[0] # cost ending at house 0 per color
for house in costs[1:]:
r, g, b = (house[0] + min(g, b),
house[1] + min(r, b),
house[2] + min(r, g))
return min(r, g, b)Pseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Only tracking the single cheapest previous color — when the current house would use the same cheapest color, you need the second cheapest as a fallback. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.