LeetCode1473. 粉刷房子 III(三维动态规划)
Posted 醉苼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode1473. 粉刷房子 III(三维动态规划)相关的知识,希望对你有一定的参考价值。
链接:https://leetcode-cn.com/problems/paint-house-iii/solution/javasan-wei-dong-tai-gui-hua-by-oyzg-qujd/
解题思路
参考Qian神的讲解https://leetcode-cn.com/problems/paint-house-iii/solution/c-san-wei-dong-tai-gui-hua-by-qiank-yn5l/
1.dp[i][j][k]代表前i个房子组成j个街区,且第i个房子颜色为k;
2.状态转移方程:
- 当前房子有颜色
有颜色的话是否与前一个房子相等?
相等的话 dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j][cur_color]);//没有形成新的街道
不相等的话 dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j-1][prv_color]);//形成了新的街道
- 当前房子没有颜色
没有颜色的话就要涂颜色
如果涂的颜色和前一个颜色相同
dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j][prv_color]+cost[i][cur_color-1]);
如果涂的颜色和前一个房子颜色不同
dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j-1][prv_color]+cost[i][cur_color-1]);
3.初始化 将数组中每一个数初始化为一个大数 0x3f3f3f3f,不能初始化为Integer.MAX_VALUE,因为后面的运算中可能导致溢出
4.结果 取dp[m-1][target]中的最小值 如果最小值等于0x3f3f3f3f,返回-1
代码:
class Solution {
public int minCost(int[] houses, int[][] cost, int m, int n, int target) {
int[][][] dp = new int[m][target+1][n+1];
//初始化
for(int i = 0; i < m; i++) {
for(int j = 0; j <= target; j++) {
for(int k = 0; k <= n; k++) {
dp[i][j][k] = 0x3f3f3f3f;
}
}
}
if(houses[0] == 0) {
for(int k = 1; k <= n; k++) {
dp[0][1][k] = cost[0][k-1];
}
} else {
dp[0][1][houses[0]] = 0;
}
//推导
for(int i = 1; i < m; i++) {
//如果当前房子没有颜色
if(houses[i] == 0) {
for(int cur_color = 1; cur_color <= n; cur_color++) {
for(int prv_color = 1; prv_color <= n; prv_color++) {
for(int j = 1; j <= target; j++) {
if(cur_color == prv_color) {
dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j][prv_color]+cost[i][cur_color-1]);
} else {
dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j-1][prv_color]+cost[i][cur_color-1]);
}
}
}
}
} else {//如果当前房子没有颜色
int cur_color = houses[i];
for(int prv_color = 1; prv_color <= n; prv_color++) {
for(int j = 1; j <= target; j++) {
if(cur_color == prv_color) {
dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j][cur_color]);
} else {
dp[i][j][cur_color] = Math.min(dp[i][j][cur_color], dp[i-1][j-1][prv_color]);
}
}
}
}
}
//取dp[m-1][target]中的最小值
int ans = dp[m-1][target][0];
for(int i = 1; i <= n; i++) {
ans = Math.min(ans, dp[m-1][target][i]);
}
return ans == 0x3f3f3f3f ? -1 : ans;
}
}
以上是关于LeetCode1473. 粉刷房子 III(三维动态规划)的主要内容,如果未能解决你的问题,请参考以下文章
leetcode1473. 粉刷房子 III(超难的三维dp问题)
LeetCode 剑指 Offer II 091.粉刷房子 - 原地修改
Python描述 LeetCode 剑指 Offer II 091. 粉刷房子