每日3题(1)-粉刷房子

2022-06-26  本文已影响0人  程序员小2

题目:

假如有一排房子,共 n 个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。

当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n x 3 的正整数矩阵 costs 来表示的。

例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2] 表示第 1 号房子粉刷成绿色的花费,以此类推。

请计算出粉刷完所有房子最少的花费成本。

示例 1:

输入: costs = [[17,2,17],[16,16,5],[14,3,19]]
输出: 10
解释: 将 0 号房子粉刷成蓝色,1 号房子粉刷成绿色,2 号房子粉刷成蓝色。
最少花费: 2 + 5 + 3 = 10。
示例 2:

输入: costs = [[7,6,2]]
输出: 2

提示:

costs.length == n
costs[i].length == 3
1 <= n <= 100
1 <= costs[i][j] <= 20

思路:

动态规划
当已知粉刷前 ii个房子的最小花费成本时,根据粉刷第 i+1 号房子的花费成本可以计算粉刷前 i + 1 个房子的最小花费成本,因此可以使用动态规划计算最小花费成本。

用dp[i][j] 表示粉刷第 0号房子到第 i号房子且第 i 号房子被粉刷成第 j种颜色时的最小花费成本。由于一共有 n 个房子和 3 种颜色,因此 0≤i<n,0≤j<3。

当只有第 00 号房子被粉刷时,对于每一种颜色,总花费成本即为将第 00 号房子粉刷成该颜色的花费成本,因此边界条件是:对于任意 0 \le j < 30≤j<3,\textit{dp}[0][j] = \textit{costs}[0][j]dp[0][j]=costs[0][j]。

dp[i][0] =min(dp[i−1][1],dp[i−1][2])+costs[i][0]
dp[i][1]=min(dp[i−1][0],dp[i−1][2])+costs[i][1]
dp[i][2]=min(dp[i−1][0],dp[i−1][1])+costs[i][2]

计算结束时,dp[n−1] 中的最小值即为粉刷所有房子的最小花费成本。

当 i≥1 时,由于dp[i] 的计算只和 dp[i−1] 有关,因此可以使用滚动数组优化空间,将空间复杂度降低到 O(1)

java代码:

class Solution {
     public int minCost(int[][] costs) {
        int n = costs.length;
        int[] dp = new int[3];
        for (int i = 0; i < 3; i++) {
            dp[i] = costs[0][i];
        }

        for (int i = 1; i < n; i++) {
            int[] dpNew = new int[3];
            dpNew[0] = Math.min(dp[1], dp[2]) + costs[i][0];
            dpNew[1] = Math.min(dp[0], dp[2]) + costs[i][1];
            dpNew[2] = Math.min(dp[0], dp[1]) + costs[i][2];

            dp = dpNew;
        }

        return Arrays.stream(dp).min().getAsInt();
    }
}
上一篇下一篇

猜你喜欢

热点阅读