515. 房屋染色(序列类型动态规划)

序列型动态规划

  • 序列型动态规划:…前i个…最小/方式数/可行性
  • 在设计动态规划的过程中,发现需要知道前n-1栋房子的最优策略中,房子n-2的颜色
  • 如果只用f[N-1],将无法区分
  • 解决方法:记录下房子n-2的颜色
  • 在房子N-2是红/蓝/绿色的情况下,油漆前n-1栋房子的最小花费
  • 序列+状态

示例

/**
* 515. 房屋染色
*   这里有n个房子在一列直线上,现在我们需要给房屋染色,分别有红色蓝 色和绿色。每个房屋染不同的颜色费用也不同,你需要设计一种染色方案使得相邻的房屋颜色不同,并且费用最小,返回最小的费用。
	费用通过一个nx3 的矩阵给出,比如cost[0][0]表示房屋0染红色的费用,cost[1][2]表示房屋1染绿色的费用。
	
	样例
	样例 1:
	
	输入: [[14,2,11],[11,14,5],[14,3,10]]
	输出: 10
	解释: 第一个屋子染蓝色,第二个染绿色,第三个染蓝色,最小花费:2 + 5 + 3 = 10.
*/
public class Solution {
    /**
     * @param costs: n x 3 cost matrix
     * @return: An integer, the minimum cost to paint all houses
     */
    public int minCost(int[][] costs) {
        // write your code here
        int n = costs.length;
        if(n == 0){
            return 0;
        }
        int m = costs[0].length;
        if(m == 0){
            return 0;
        }
        // 构建状态数组,确定状态f[i][j]表示前i栋楼颜色为j情况下最小代价
        // 最后一步:f[i][j]可由前i-1栋且颜色不为j子问题
        // 子问题:到达状态f[i-1][!j]最小的代价 
        int[][] f = new int[n+1][m];
        // 初始状态也就是前0栋房子的染色代价都为0
        f[0][0] = f[0][1] = f[0][2] = 0;
		// 通过状态转移方程求1到n栋楼下3种涂色情况分别的最小代价
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < m; j++){
                f[i][j] = Integer.MAX_VALUE;
                for(int k = 0; k < m; k++){
                    if(k == j){
                        continue;
                    }
                    if(f[i-1][k] + costs[i-1][j] < f[i][j]){
                        f[i][j] = f[i-1][k] + costs[i-1][j];
                    }
                }
            }
        }
        int res = f[n][0];
        if(f[n][1] < res){
            res = f[n][1];
        }
        if(f[n][2] < res){
            res = f[n][2];
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值