当前位置:网站首页>【剑指 Offer II 091. 粉刷房子】
【剑指 Offer II 091. 粉刷房子】
2022-08-09 14:56:00 【wangyunpeng33】
剑指 Offer II 091. 粉刷房子
假如有一排房子,共 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
题解
动态规划
每个房子可以被粉刷成三种颜色中的一种,需要计算在满足相邻房子的颜色不同的情况下粉刷所有房子的最小花费成本。由于当已知粉刷前 ii 个房子的最小花费成本时,根据粉刷第 i + 1 i+1 i+1 号房子的花费成本可以计算粉刷前 i + 1 i+1 i+1个房子的最小花费成本,因此可以使用动态规划计算最小花费成本。
由于每个房子可以被粉刷成三种颜色中的一种,因此需要分别考虑粉刷成三种颜色时的最小花费成本。
用 dp [ i ] [ j ] \textit{dp}[i][j] dp[i][j] 表示粉刷第 0 号房子到第 i 号房子且第 i 号房子被粉刷成第 j 种颜色时的最小花费成本。由于一共有 n 个房子和 3 种颜色,因此 0 ≤ i < n 0≤i<n 0≤i<n, 0 ≤ j < 3 0≤j<3 0≤j<3。
当只有第 0 号房子被粉刷时,对于每一种颜色,总花费成本即为将第 0 号房子粉刷成该颜色的花费成本,因此边界条件是:对于任意 0 ≤ j < 3 , dp [ 0 ] [ j ] = costs [ 0 ] [ j ] 0≤j<3,\textit{dp}[0][j] = \textit{costs}[0][j] 0≤j<3,dp[0][j]=costs[0][j]。
对于 1 ≤ i < n 1≤i<n 1≤i<n,第 i 号房子和第 i−1 号房子的颜色必须不同,因此当第 i 号房子被粉刷成某一种颜色时,第 i−1 号房子只能被粉刷成另外两种颜色之一。当第 i 号房子分别被粉刷成三种颜色时,粉刷第 0 号房子到第 i 号房子的最小花费成本计算如下:
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 ] \begin{aligned} \textit{dp}[i][0] &= \min(\textit{dp}[i - 1][1], \textit{dp}[i - 1][2]) + \textit{costs}[i][0] \\ \textit{dp}[i][1] &= \min(\textit{dp}[i - 1][0], \textit{dp}[i - 1][2]) + \textit{costs}[i][1] \\ \textit{dp}[i][2] &= \min(\textit{dp}[i - 1][0], \textit{dp}[i - 1][1]) + \textit{costs}[i][2] \end{aligned} dp[i][0]dp[i][1]dp[i][2]=min(dp[i−1][1],dp[i−1][2])+costs[i][0]=min(dp[i−1][0],dp[i−1][2])+costs[i][1]=min(dp[i−1][0],dp[i−1][1])+costs[i][2]
三种颜色的情况可以合并为一个状态转移方程,对于 1 ≤ i < n 1≤i<n 1≤i<n 和 0 ≤ j < 3 0≤j<3 0≤j<3,状态转移方程如下:
dp [ i ] [ j ] = min ( dp [ i − 1 ] [ ( j + 1 ) m o d 3 ] , \textit{dp}[i][j] = \min(\textit{dp}[i - 1][(j + 1) \bmod 3], dp[i][j]=min(dp[i−1][(j+1)mod3],
dp [ i − 1 ] [ ( j + 2 ) m o d 3 ] ) + costs [ i ] [ j ] \textit{dp}[i - 1][(j + 2) \bmod 3]) + \textit{costs}[i][j] dp[i−1][(j+2)mod3])+costs[i][j]
计算结束时, dp [ n − 1 ] \textit{dp}[n - 1] dp[n−1] 中的最小值即为粉刷所有房子的最小花费成本。
当 i ≥ 1 i≥1 i≥1 时,由于 dp [ i ] \textit{dp}[i] dp[i]的计算只和 dp [ i − 1 ] \textit{dp}[i - 1] dp[i−1] 有关,因此可以使用滚动数组优化空间,将空间复杂度降低到 O ( 1 ) O(1) O(1)。
代码
class Solution:
def minCost(self, costs: List[List[int]]) -> int:
dp = costs[0]
for i in range(1, len(costs)):
dp = [min(dp[j - 1], dp[j - 2]) + c for j, c in enumerate(costs[i])]
return min(dp)
边栏推荐
- 内存泄露检测工具VLD(Visual Leak Detector)使用说明
- A shortcut method for writing menu commands in C
- .Net Core 技巧小结
- 单向链表几个比较重要的函数(包括插入、删除、反转等)
- MouStart指纹浏览器怎么防关联
- C#轻量级ORM使用 Dapper+Contrib
- 利用qrcode组件实现图片转二维码
- Inverted order at the beginning of the C language 】 【 string (type I like Beijing. Output Beijing. Like I)
- Arduino 飞鼠 空中鼠标 陀螺仪体感鼠标
- 防关联浏览器对亚马逊测评有多重要?
猜你喜欢

Different compilers, different modes, impact on results

你知道亚马逊代运营的成本是多少吗?

Simply record offsetof and container_of

地铁预约Postman脚本使用
Example of file operations - downloading and merging streaming video files
It is deeply recognized that the compiler can cause differences in the compilation results

抱抱脸(hugging face)教程-中文翻译-分享一个模型

ImageWatch无法显示图像

小型项目如何使用异步任务管理器实现不同业务间的解耦

SNR 信噪比
随机推荐
It is deeply recognized that the compiler can cause differences in the compilation results
The recycle bin has been showed no problem to empty the icon
流式布局总结
对导入的 excel 的时间的处理 将excel表中的时间,转成 标准的时间
YOLOV1详解
抱抱脸(hugging face)教程-中文翻译-创建一个自定义架构
内存泄露检测工具VLD(Visual Leak Detector)使用说明
pyspark.sql之实现collect_list的排序
.Net Core动态注入
什么是跨境电商测评?
鸡生蛋,蛋生鸡问题。JS顶级对象Function,Object关系
Arduino 飞鼠 空中鼠标 陀螺仪体感鼠标
【C语言初阶】详解分支语句
二叉排序树的左旋与右旋
【C语言初阶】求最小公倍数的三种方法
stream去重相同属性对象
微信小程序tabs
【C语言初阶】倒置字符串(输入 I like beijing. 输出beijing. like I)
Retrofit2 初印象?
升职加薪之SQL索引