Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find minimum cost for painting houses in Python
Suppose there is an array of size m representing m houses in a small city. Each house must be painted with one of the n colors (labeled from 1 to n). Some houses are already painted, so no need to paint them again. Houses colored with the same adjacent color form a neighborhood.
We have the array houses, where houses[i] represents the color of house i. If the color value is 0, the house is not colored yet. We have another array called cost, which is a 2D array where cost[i][j] represents the cost to color house i with color j+1. We also have a target value representing the exact number of neighborhoods we want.
We need to find the minimum cost to paint all remaining houses such that there are exactly target neighborhoods. If no solution exists, return -1.
Problem Example
If houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], n = 2, and target = 3, the output should be 11. We can paint the houses as [2,2,1,2,2], creating three neighborhoods: [{2,2}, {1}, {2,2}]. The cost to paint the first and last house is 10 + 1 = 11.
Algorithm Steps
We'll use dynamic programming with recursion ?
Define a helper function that takes current house index, previous color, and current group count
If we've processed all houses, return 0 if group count equals target, otherwise return infinity
If current house is already painted, recurse with that color
If current house needs painting, try all possible colors and choose minimum cost
Implementation
def solve(houses, cost, n, target):
m = len(houses)
def helper(i, p_col, grp):
# Base case: all houses processed
if i == m:
return 0 if grp == target else float('inf')
# House already painted
if houses[i] != 0:
# New neighborhood if color changes
new_grp = grp + (1 if p_col != houses[i] else 0)
return helper(i + 1, houses[i], new_grp)
# Try all colors for unpainted house
total = float('inf')
for col in range(1, n + 1):
paint_cost = cost[i][col - 1]
new_grp = grp + (1 if p_col != col else 0)
total = min(total, paint_cost + helper(i + 1, col, new_grp))
return total
# Start with house 0, no previous color (-1), 0 groups
ans = helper(0, -1, 0)
return ans if ans != float('inf') else -1
# Test the solution
houses = [0, 2, 1, 2, 0]
cost = [[1, 10], [10, 1], [10, 1], [1, 10], [5, 1]]
n = 2
target = 3
result = solve(houses, cost, n, target)
print(f"Minimum cost: {result}")
Minimum cost: 11
How It Works
The algorithm uses recursion with three parameters ?
i: Current house index being processed
p_col: Previous house color (to detect neighborhood boundaries)
grp: Current number of neighborhoods formed
A new neighborhood is created when the current house color differs from the previous house color. The algorithm explores all possible color combinations and returns the minimum cost that achieves exactly the target number of neighborhoods.
Optimized Version with Memoization
def solve_optimized(houses, cost, n, target):
m = len(houses)
memo = {}
def helper(i, p_col, grp):
# Memoization key
key = (i, p_col, grp)
if key in memo:
return memo[key]
# Base case
if i == m:
result = 0 if grp == target else float('inf')
memo[key] = result
return result
# House already painted
if houses[i] != 0:
new_grp = grp + (1 if p_col != houses[i] else 0)
result = helper(i + 1, houses[i], new_grp)
memo[key] = result
return result
# Try all colors
total = float('inf')
for col in range(1, n + 1):
paint_cost = cost[i][col - 1]
new_grp = grp + (1 if p_col != col else 0)
total = min(total, paint_cost + helper(i + 1, col, new_grp))
memo[key] = total
return total
ans = helper(0, -1, 0)
return ans if ans != float('inf') else -1
# Test optimized version
result_opt = solve_optimized(houses, cost, n, target)
print(f"Optimized result: {result_opt}")
Optimized result: 11
Conclusion
This dynamic programming solution efficiently finds the minimum cost to paint houses with exactly the target number of neighborhoods. The memoized version improves performance by avoiding redundant calculations, making it suitable for larger inputs.
