动态规划学习

坐标型动态规划

序列型动态规划

划分型动态规划

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值