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 粉刷房子合集

LeetCode 剑指 Offer II 091.粉刷房子 - 原地修改

Python描述 LeetCode 剑指 Offer II 091. 粉刷房子

Python描述 LeetCode 剑指 Offer II 091. 粉刷房子

Python描述 LeetCode 剑指 Offer II 091. 粉刷房子