坐标型动态规划
序列型动态规划
划分型动态规划
1.给定m行n列的网格,有一个机器人从左上角(0,0)出发,每一步可以向下或者向右走一步,网格中有些地方有障碍,机器人不能通过障碍格,问有多少种方式走到右下角?
-
最后一步一定是从左边(i,j-1)或上边(i-1,j)过来
-
状态f[i] [j]表示从左上角有多种方式走到格子(i,j)
-
如果左上角(0,0)格或者右上角(m-1,n-1)格有障碍,直接输出0
-
如果(i,j)格有障碍,f[i] [j]=0 表示机器人不能到达此格
-
初始条件f[0] [0] = 1
public int uniquePathWithObstacles(int[][] A){
int m = A.length;
if (m==0){
return 0;
}
int n = A[0].length;
if (n==0){
return 0;
}
int[][] f = new int[m][n];
int i, j;
for (i=0;i<m;i++){
for(j=0;j<n;++j){
if(A[i][j] == 1){
f[i][j] = 0;
}else{
if(i==0&&j==0){
f[i][j] = 1;
}else{
f[i][j] = 0;
if(i-1>=0){
f[i][j] += f[i-1][j];
}
if(j-1>=0){
f[i][j]+=f[i][j-1];
}
}
}
}
}
return f[m-1][n-1]
}
2.有一排N栋房子,每栋房子要漆成3种颜色中的一种:红、蓝、绿。任何两栋相邻房子不能漆成同样颜色。第i栋房子染成红、蓝、绿的花费分别为cost[i] [0],cost[i] [1],cost[i] [2],请问最少需要花多少钱油漆这些房子
例子:
输入:N = 3,Cost = [[14,2,11],[11,14,5],[14,3,10]]
输出:10(第0栋房子蓝色,第1栋房子绿色,第二栋房子蓝色)
确定状态
- 最优策略是花费最小的策略,最后一步:最优策略中的房子N-1染成了红、蓝、绿中的一种,但是相邻两栋房子不能漆成一种颜色。所以如果最优策略中的房子N-1是红色,房子N-2只能是蓝色或绿色,所以如果最优策略中的房子N-1是蓝色,房子N-2只能是红色或绿色,所以如果最优策略中的房子N-1是绿色,房子N-2只能是![在这里插入图片描述]
蓝色或红色。分别记录油漆前N-1栋房子并且房子N-2是红色、蓝色、绿色的最小花费 - 需要知道油漆前N-1栋房子并且房子N-2是红色、蓝色、绿色的最小花费
- 子问题:状态:设油漆前i栋房子并且房子i-1是红色、蓝色、绿色的最小花费分别为f[i] [0], f[i] [1], f[i] [2]
转移方程
f[i] [0] = min{f[i-1] [1]+ cost[i-1] [0],f[i-1] [2]+ cost [i-1] [1]
- f[i] [1] = min{f[i-1] [0]+ cost[i-1] [1],f[i-1] [2]+ cost [i-1] [1]
- f[i] [2] = min{f[i-1] [0]+ cost[i-1] [2],f[i-1] [1]+ cost [i-1] [2]
初始条件和边界情况
- 初始条件:f[0] [0] = f[0] [1] = f[0] [2] = 0
计算顺序
- 初始化f[0] [0], f[0] [1],f[0] [2]
- 计算f[1] [0], f[1] [1] , f[1] [2]
- …
- 计算f[N] [0] , f[N] [1], f[N] [2]
- 结果是:min{f[N] [0], f[N] [1], f[N] [2]} 时间复杂度O(N),空间复杂度O(N)
public int minCost(int[][] cost){
int n = cost.length;
if (n==0){
return 0;
}
int [][] f = new int[n+1][3];
int i, j ,k;
f[0][0] = f[0][1] = f[0][2] = 0;
for(i = 1;i<=n;++i){
for(j = 0;j<3;++j){
f[i][j] = Integer.MAX_VALUE;
for(k = 0;k < 3;++k){
if (j == k){
continue;
}
if (f[i-1][k]+cost[i-1][j]<f[i][j]){
f[i][j] = f[i-1][k] + cost[i-1][j];
}
}
}
}
res = f[n][0];
if (f[n][1]<res){
res = f[n][1];
}
if (f[n][2]<res){
res = f[n][2];
}
return res;
}