这是一道典型的多状态动态规划问题。
const[n][0],const[n][1],const[n][2],分别表示将第n个房间涂为红色,蓝色,绿色的花费。
题目要求相邻的房间涂色不能相同,假设第i间房间涂红色,那么第i-1间房间只能涂绿色或蓝色,所以当前涂红色的情况下,最小花费就是前一间房间涂绿色或者蓝色时候的最小花费。这时候我们就可以建立三个数组,来分别表示第i个房间涂红色,绿色,蓝色时的最小花费。假设这三个数组分别为dpr(红色),dpg(绿色),dpb(蓝色),dpr[ i ]表示,第i间涂红色时候的最小花费,其余两个类似。
因为我们就可以写状态转移方程,因为第i间如果涂红色,那么第i-1间只能是绿色或蓝色,所以dpr[ i ]= min(dpg[i-1],dpb[i-1)+const[i-1][0];这是第i间涂红色,第i间涂绿色,蓝色也是如此分析, 涂蓝色 :dpb[i]=min(dpr[i-1],dpg[i-1])+costs[i-1][1];
涂绿色:dpg[i]=min(dpr[i-1],dpb[i-1])+costs[i-1][2];
注:例上述状态转移方程中const[i-1][1],const为[i-1]是因为我们 i 的计数是从1开始的,而题目中const的存储是从0开始的,为了方便处理边界情况,所以这样处理。
因为以上三种情况都是我们假设的情况,而实际需要最小花费,所以最后找出三者中的最小值即为最后要返回的值。
初始化的问题,在涂第一间房子的时候,花费的费用就是涂所对应颜色的花费,所以dpr[0] dpg[0] dpb[0] 的值为0 即可。
代码如下:
int minCost(vector<vector<int>>& costs) {
int n = costs.size();
vector<int> dpr(n+1);
vector<int> dpb(n+1);
vector<int> dpg(n+1);
for(int i = 1;i<dpr.size();i++)
{
dpr[i]=min(dpb[i-1],dpg[i-1])+costs[i-1][0];
//i处涂红色
dpb[i]=min(dpr[i-1],dpg[i-1])+costs[i-1][1];
//i处涂蓝色
dpg[i]=min(dpr[i-1],dpb[i-1])+costs[i-1][2];
//i处涂绿色
}
return min(dpr[n],min(dpb[n],dpg[n]));
}
欢迎大家在评论区交流讨论,批评指正。