一道简单的DP问题,但是数据给的太小了,感觉暴力都能做,虽然我没想过
状态转移:
当前涂某个颜色的最小价格是前面另外两个颜色较便宜的一个的价格加上当前颜色的价格
状态转移方程:
f[0][i] = Math.min(f[1][i-1], f[2][i-1]) + costs[i-1][0];
f[1][i] = Math.min(f[0][i-1], f[2][i-1]) + costs[i-1][1];
f[2][i] = Math.min(f[0][i-1], f[1][i-1]) + costs[i-1][2];
class Solution {
public int minCost(int[][] costs) {
int n = costs.length;
int[][] f = new int[3][n+10];
f[0][0] = f[1][0] = f[2][0] = 0;
for(int i = 1; i<=n; i++){
f[0][i] = Math.min(f[1][i-1], f[2][i-1]) + costs[i-1][0];
f[1][i] = Math.min(f[0][i-1], f[2][i-1]) + costs[i-1][1];
f[2][i] = Math.min(f[0][i-1], f[1][i-1]) + costs[i-1][2];
}
int min = Math.min(f[0][n],f[1][n]);
return Math.min(min,f[2][n]);
}
}
- 时间复杂度O(n)
- 空间复杂度O(n)//由于只需要前面的值,可使用动态数组使空间复杂度将为O(1)
动态数组优化
class Solution {
int[][] f = new int[3][2];
void swap(){
for(int i=0; i<3; i++){
int tmp = f[i][0];
f[i][0] = f[i][1];
f[i][1] = tmp;
}
}
public int minCost(int[][] costs) {
int n = costs.length;
f[0][0] = f[1][0] = f[2][0] = 0;
for(int i = 1; i<=n; i++){
f[0][1] = Math.min(f[1][0], f[2][0]) + costs[i-1][0];
f[1][1] = Math.min(f[0]0], f[2][0]) + costs[i-1][1];
f[2][1] = Math.min(f[0][0], f[1][0]) + costs[i-1][2];
swap();
}
int min = Math.min(f[0][0],f[1][0]);
return Math.min(min,f[2][0]);
}
}
- 时间复杂度O(n)
- 空间复杂度O(1)//但实际上,由于数据较少,这种做法效果还没有上面的好