比较典型的动态规划。
如果把重点放在当前房子和上一个相同,还是不同来做就做不出来,所以干脆枚举每个房子的情况。
dp[i][0] = costs[i][0] + Math.min(dp[i-1][1],dp[i-1][2]);
dp[i][1] = costs[i][1] + Math.min(dp[i-1][0],dp[i-1][2]);
dp[i][2] = costs[i][2] + Math.min(dp[i-1][1],dp[i-1][0]);
然后其实A B C用3个变量记录上一个房子的3种情况就行了,不用数组。
public class Solution
{
public int minCost(int[][] costs)
{
int num = costs.length;
if(num == 0) return 0;
int a = costs[0][0];
int b = costs[0][1];
int c = costs[0][2];
for(int i = 1; i < num;i++)
{
int a2,b2,c2;
a2 = costs[i][0] + Math.min(b,c);
b2 = costs[i][1] + Math.min(a,c);
c2 = costs[i][2] + Math.min(a,b);
a = a2; b = b2; c = c2;
}
return Math.min(Math.min(a,b),c);
}
}
动态规划是坑啊,想了半天没想到这么简单。。
二刷。
N的状态与N-1有关。
比较triky的时候每一步的三个种情况都要算下来。
N选绿,看n-1是蓝好还是红好。
N选哄,看 ....蓝......绿..。
...蓝,.......红......绿..。
最后看n选红绿蓝比较下就行。。
Time: O(n)
Space: O(1) (有人指出可以without extra space...在原数组上修改。。。。)
public class Solution {
public int minCost(int[][] costs) {
if (costs.length == 0) return 0;
if (costs.length == 1) return Math.max(Math.max(costs[0][1], costs[0][0]), costs[0][2]);
int[] red = new int[2];
int[] green = new int[2];
int[] blue = new int[2];
red[0] = costs[0][0];
blue[0] = costs[0][1];
green[0] = costs[0][2];
for (int i = 1; i < costs.length; i++) {
red[i%2] = Math.min(green[(i-1)%2], blue[(i-1)%2]) + costs[i][0];
blue[i%2] = Math.min(red[(i-1)%2], green[(i-1)%2]) + costs[i][1];
green[i%2] = Math.min(red[(i-1)%2], blue[(i-1)%2]) + costs[i][2];
}
int len = costs.length - 1;
return Math.min(red[len%2], Math.min(blue[len%2], green[len%2]));
}
}