LeetCode每日一题(1473. Paint House III)

There is a row of m houses in a small city, each house must be painted with one of the n colors (labeled from 1 to n), some houses that have been painted last summer should not be painted again.

A neighborhood is a maximal group of continuous houses that are painted with the same color.

For example: houses = [1,2,2,3,3,2,1,1] contains 5 neighborhoods [{1}, {2,2}, {3,3}, {2}, {1,1}].
Given an array houses, an m x n matrix cost and an integer target where:

houses[i]: is the color of the house i, and 0 if the house is not painted yet.
cost[i][j]: is the cost of paint the house i with the color j + 1.
Return the minimum cost of painting all the remaining houses in such a way that there are exactly target neighborhoods. If it is not possible, return -1.

Example 1:

Input: houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
Output: 9

Explanation: Paint houses of this way [1,2,2,1,1]
This array contains target = 3 neighborhoods, [{1}, {2,2}, {1,1}].
Cost of paint all houses (1 + 1 + 1 + 1 + 5) = 9.

Example 2:

Input: houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
Output: 11

Explanation: Some houses are already painted, Paint the houses of this way [2,2,1,2,2]
This array contains target = 3 neighborhoods, [{2,2}, {1}, {2,2}].
Cost of paint the first and last house (10 + 1) = 11.

Example 3:

Input: houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], m = 4, n = 3, target = 3
Output: -1

Explanation: Houses are already painted with a total of 4 neighborhoods [{3},{1},{2},{3}] different of target = 3.

Constraints:

  • m == houses.length == cost.length
  • n == cost[i].length
  • 1 <= m <= 100
  • 1 <= n <= 20
  • 1 <= target <= m
  • 0 <= houses[i] <= n
  • 1 <= cost[i][j] <= 104

dp[i][j][k]代表前 i 栋房子在第 i 栋为 j 颜色(有可能是涂成的,也有可能是本来就是)且这 i 栋房子中已经出现了 k 组相邻且颜色相同的组的情况下的最小成本。那只需要考虑以下几种情况:

  1. 第 i 栋房子需要喷涂,且与 i-1 房子同色的成本是 dp[i-1][j][k] + cost[i][j]
  2. 第 i 栋房子需要喷涂,与 i-1 房子不同色的成本是 min(dp[i-1][0][k-1], dp[i-1][1][k-1], …, dp[i-1][j-1][k-1], dp[i-1][j+1][k-1], …) + cost[i][j]
  3. 第 i 栋房子不需要喷涂, 且与 i-1 房子同色的成本是 dp[i-1][c][k]其中 c 为当前房子的颜色
  4. 第 i 栋房子不需要喷涂,且与 i-1 房子不同色的成本是 min(dp[i-1][0][k-1], dp[i-1][1][k-1], …, dp[i-1][c-1][k-1], dp[i-1][c+1][k-1])其中 c 为当前房子的颜色


impl Solution {
    pub fn min_cost(houses: Vec<i32>, cost: Vec<Vec<i32>>, m: i32, n: i32, target: i32) -> i32 {
        let mut dp =
            vec![vec![vec![i32::MAX; target as usize + 1]; n as usize + 1]; m as usize + 1];
        for j in 0..=n as usize {
            dp[0][j] = vec![0; target as usize + 1];
        }
        for i in 1..=m as usize {
            for j in 1..=n as usize {
                for k in 1..=target as usize {
                    if k > i {
                        break;
                    }
                    if houses[i - 1] != 0 {
                        if houses[i - 1] as usize != j {
                            continue;
                        }
                        let same = dp[i - 1][j][k];
                        let diff = {
                            let mut min = i32::MAX;
                            for jj in 0..=n as usize {
                                if jj != j {
                                    min = min.min(dp[i - 1][jj][k - 1]);
                                }
                            }
                            min
                        };
                        dp[i][j][k] = same.min(diff);
                        continue;
                    }
                    let same = {
                        let prev = dp[i - 1][j][k];
                        if prev == i32::MAX {
                            i32::MAX
                        } else {
                            let curr = cost[i - 1][j - 1];
                            prev + curr
                        }
                    };
                    let diff = {
                        let mut min = i32::MAX;
                        for jj in 1..=n as usize {
                            if j != jj {
                                let prev = dp[i - 1][jj][k - 1];
                                if prev == i32::MAX {
                                    continue;
                                }
                                let curr = cost[i - 1][j - 1];
                                min = min.min(prev + curr);
                            }
                        }
                        min
                    };
                    dp[i][j][k] = same.min(diff);
                }
            }
        }
        let mut ans = i32::MAX;
        for j in 1..=n as usize {
            ans = ans.min(dp[m as usize][j][target as usize]);
        }
        if ans == i32::MAX {
            return -1;
        }
        ans
    }
}

你可能感兴趣的:(数据结构,算法,算法,leetcode)