1473. 粉刷房子 III(三维动态规划)
题目来源:1473. 粉刷房子 III
// 在一个小城市里,有 m 个房子排成一排,你需要给每个房子涂上 n 种颜色之一(颜色编号为 1 到 n )。
// 有的房子去年夏天已经涂过颜色了,所以这些房子不需要被重新涂色。
// 我们将连续相同颜色尽可能多的房子称为一个街区。(比方说 houses = [1,2,2,3,3,2,1,1] ,
// 它包含 5 个街区 [{1}, {2,2}, {3,3}, {2}, {1,1}] 。)
// 给你一个数组 houses ,一个 m * n 的矩阵 cost 和一个整数 target ,其中:
// houses[i]:是第 i 个房子的颜色,0 表示这个房子还没有被涂色。
// cost[i][j]:是将第 i 个房子涂成颜色 j+1 的花费。
// 请你返回房子涂色方案的最小总花费,使得每个房子都被涂色后,恰好组成 target 个街区。如果没有可用的涂色方案,请返回 -1 。
/** * @param {number[]} houses * @param {number[][]} cost * @param {number} m * @param {number} n * @param {number} target * @return {number} */ var minCost = function(houses, cost, m, n, target) { houses = houses.map((c)=>--c); let dp = new Array(m).fill(0) .map(()=>new Array(n).fill(0) .map(()=>new Array(target).fill(Number.MAX_VALUE))); for(let i=0;i<m;i++){ for(let j=0;j<n;j++){ if(houses[i] != -1 && houses[i] != j){ continue; } for(let k = 0;k<target;k++){ for(let j0=0;j0<n;j0++){ if(j0 === j){ if(i===0){ if(k===0){ dp[i][j][k] = 0; } }else{ dp[i][j][k] = Math.min(dp[i][j][k], dp[i-1][j][k]); } }else if(i>0 && k>0){ dp[i][j][k] = Math.min(dp[i][j][k], dp[i-1][j0][k-1]); } } if(dp[i][j][k] !== Number.MAX_VALUE && houses[i] == -1){ dp[i][j][k] += cost[i][j]; } } } } let res = Number.MAX_VALUE; for(let j=0;j<n;j++){ res = Math.min(res, dp[m-1][j][target-1]); } return res === Number.MAX_VALUE?-1:res; }
let houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
console.log(houses, cost, m,n,target, minCost(houses,cost,m,n,target))
houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], m = 4, n = 3, target = 3
console.log(houses, cost, m,n,target, minCost(houses,cost,m,n,target))