【算法 & 动态规划 &路径问题】二维dp问题

解题思路

状态表示常用思路

  • dp[i][j] 表示从起始点(如 0,0) 到 i,j 位置满足题目要求的值
    • 填表顺序就是从左到右, 从上到下
  • dp[i][j] 表示从点 i,j 到 指定位置 满足题目要求的值
    • 填表顺序就是从右到左, 从下到上

不同路径(medium)

题目链接

解题思路: 动态规划

  1. 状态表示: dp[i][j] 表示从 0,0 到 i,j 最多可以有多少条路径
  2. 状态转移方程
    • 依据机器人可以向下走或者向右走来分析状态转移方程
    • 向下走: 说明 (i,j) 可以由 (i-1,j) 位置过来 => dp[i][j] = dp[i-1][j]
    • 向右走: 说明 (i,j) 可以由 (i,j - 1) 位置过来 => dp[i][j] = dp[i][j - 1]
    • 综上所述: dp[i][j] = dp[i-1] [j] + dp[i][j-1]
  3. 初始化
    • 依据状态转移方程以及取值范围, 行和列都多开辟一维
    • 为了保证填表的准确性: dp[0][1] = 1
  4. 填表顺序: 从左到右, 从上到下
  5. 返回值: dp[m][n]

代码:

class Solution {
    public int uniquePaths(int m, int n) {
        // dp[i][j] 表示从 1,1 到 i,j 一共有多少种走法
        // dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        int[][] dp = new int[m + 1][n + 1];
        dp[0][1] = 1;
        for(int i = 1; i <= m; ++i) {
            for(int j = 1; j <= n; ++j) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m][n];
    }
}

地下城游戏(hard)

题目链接

解题思路: 动态规划

  1. 状态表示

    • 这道题如果定义成: 从起点开始, 到达 [i,j] 位置的时候, 所需的最低初始健康点数, 那么我们分析状态转移的时候会有一个问题: 就是当前的健康点数还会受到后续路径的影响。也就是从上往下的状态转移不能很好的解决问题.
    • 换另一个角度: 从[i,j] 位置出发, 到达终点时需要的最低初始健康点数.
  2. 状态转移

    • 对于dp[i][j], 从[i,j] 位置出发, 下一步会有两种选择:
      • 走到右边然后走向终点
        • 那么我们在 [i,j] 位置的最低健康点数加上这一个位置的消耗, 应该要大于等于右边位置的最低健康点数, 也就是: dp[i][j] + dungeon[i][j] >= dp[i][j+1].
        • 取dp[i][j] 的最小值, 则 dp[i][j] = dp[i][j+1] - dungeon[i][j];
      • 走到下边, 然后走向终点
        • 那么我们在 [i,j] 位置的最低健康点数加上这一个位置的消耗, 应该要大于等于下边位置的最低健康点数, 也就是: dp[i][j] + dungeon[i][j] >= dp[i+1][j].
        • 取dp[i][j] 的最小值, 则 dp[i][j] = dp[i+1][j] - dungeon[i][j];
    • 综上所述, 我们需要的是两种情况下的最小值, 因此可得状态转移方程为: dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]
    • 但是,如果当前位置的 dungeon[i][j] 是一个比较大的正数的话, dp[i][j] 的值可能变成 0 或者负数, 也就是最低点数小于 1, 那么骑士就会死亡.但是骑士只要有一点血量到该点, 就可以吃到该位置的恢复, 从而恢复血量, 也就可以继续往前走. 因此我们求出来的 dp[i][j] 如果小于等于 0 的话, 说明此时的最低初始值应该为 1, 则 dp[i][j] = max(1,dp[i][j])
  3. 初始化

    • 在 dp 表最后⾯添加⼀⾏,并且添加⼀列后,所有的值都先初始化为⽆穷⼤,然后让dp[m][n - 1] = dp[m - 1][n] = 1 即可。
  4. 填表顺序: 从下往上, 从右往左

  5. 返回值: dp[0][0]

代码

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        // dp[i][j] 表示从 i,j 位置到 右下角 最低需要的血量
        int m = dungeon.length, n = dungeon[0].length;
        int[][] dp = new int[m+1][n+1];

        for(int i = 0; i <= m; ++i) {
            dp[i][n] = Integer.MAX_VALUE;
        }

        for(int j = 0; j <= n; ++j) {
            dp[m][j] = Integer.MAX_VALUE;
        }

        dp[m][n-1] = dp[m - 1][n] = 1;

        for(int i = m - 1; i >= 0; --i) {
            for(int j = n - 1; j >= 0; --j) {
                dp[i][j] = Math.min(dp[i][j + 1],dp[i + 1][j]) - dungeon[i][j];
                dp[i][j] = Math.max(1,dp[i][j]);
            }
        }
        return dp[0][0];
    }
}
  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目录 目录 1 Graph 图论 3 | DAG 的深度优先搜索标记 3 | 无向图找桥 3 | 无向图连通度(割) 3 | 最大团问题 DP + DFS 3 | 欧拉路径 O(E) 3 | DIJKSTRA 数组实现 O(N^2) 3 | DIJKSTRA O(E * LOG E) 4 | BELLMANFORD 单源最短路 O(VE) 4 | SPFA(SHORTEST PATH FASTER ALGORITHM) 4 | 第 K 短路(DIJKSTRA) 5 | 第 K 短路(A*) 5 | PRIM 求 MST 6 | 次小生成树 O(V^2) 6 | 最小生成森林问题(K 颗树)O(MLOGM). 6 | 有向图最小树形图 6 | MINIMAL STEINER TREE 6 | TARJAN 强连通分量 7 | 弦图判断 7 | 弦图的 PERFECT ELIMINATION 点排列 7 | 稳定婚姻问题 O(N^2) 7 | 拓扑排序 8 | 无向图连通分支(DFS/BFS 邻接阵) 8 | 有向图强连通分支(DFS/BFS 邻接阵)O(N^2) 8 | 有向图最小点基(邻接阵)O(N^2) 9 | FLOYD 求最小环 9 | 2-SAT 问题 9 Network 网络流 11 | 二分图匹配(匈牙利算法 DFS 实现) 11 | 二分图匹配(匈牙利算法 BFS 实现) 11 | 二分图匹配(HOPCROFT-CARP 的算法) 11 | 二分图最佳匹配(KUHN MUNKRAS 算法 O(M*M*N)) 11 | 无向图最小割 O(N^3) 12 | 有上下界的最小(最大)流 12 | DINIC 最大流 O(V^2 * E) 12 | HLPP 最大流 O(V^3) 13 | 最小费用流 O(V * E * F) 13 | 最小费用流 O(V^2 * F) 14 | 最佳边割集 15 | 最佳点割集 15 | 最小边割集 15 | 最小点割集(点连通度) 16 | 最小路径覆盖 O(N^3) 16 | 最小点集覆盖 16 Structure 数据结构 17 | 求某天是星期几 17 | 左偏树 合并复杂度 O(LOG N) 17 | 树状数组 17 | 二维树状数组 17 | TRIE 树(K 叉) 17 | TRIE 树(左儿子又兄弟) 18 | 后缀数组 O(N * LOG N) 18 | 后缀数组 O(N) 18 | RMQ 离线算法 O(N*LOGN)+O(1) 19 | RMQ(RANGE MINIMUM/MAXIMUM QUERY)-ST 算法 (O(NLOGN + Q)) 19 | RMQ 离线算法 O(N*LOGN)+O(1)求解 LCA 19 | LCA 离线算法 O(E)+O(1) 20 | 带权值的并查集 20 | 快速排序 20 | 2 台机器工作调度 20 | 比较高效的大数 20 | 普通的大数运算 21 | 最长公共递增子序列 O(N^2) 22 | 0-1 分数规划 22 | 最长有序子序列(递增/递减/非递增/非递减) 22 | 最长公共子序列 23 | 最少找硬币问题(贪心策略-深搜实现) 23 | 棋盘分割 23 | 汉诺塔 23 | STL 中的 PRIORITY_QUEUE 24 | 堆栈 24 | 区间最大频率 24 | 取第 K 个元素 25 | 归并排序求逆序数 25 | 逆序数推排列数 25 | 二分查找 25 | 二分查找(大于等于 V 的第一个值) 25 | 所有数位相加 25 Number 数论 26 1 |递推求欧拉函数 PHI(I) 26 |单独求欧拉函数 PHI(X) 26 | GCD 最大公约数 26 | 快速 GCD 26 | 扩展 GCD 26 | 模线性方程 A * X = B (% N) 26 | 模线性方程组 26 | 筛素数 [1..N] 26 | 高效求小范围素数 [1..N] 26 | 随机素数测试(伪素数原理) 26 | 组合数学相关 26 | POLYA 计数 27 | 组合数 C(N, R) 27 | 最大 1 矩阵 27 | 约瑟夫环问题(数学方法) 27 | 约瑟夫环问题(数组模拟) 27 | 取石子游戏 1 27 | 集合划分问题 27 | 大数平方根(字符串数组表示) 28 | 大数取模的二进制方法 28 | 线性方程组 A[][]X[]=B[] 28 | 追赶法解周期性方程 28 | 阶乘最后非零位,复杂度 O(NLOGN) 29 递归方法求解排列组合问题 30 | 类循环排列 30 | 全排列 30 | 不重复排列 30 | 全组合 31 | 不重复组合 31 | 应用 31 模式串匹配问题总结 32 | 字符串 HASH 32 | KMP 匹配算法 O(M+N) 32 | KARP-RABIN 字符串匹配 32 | 基于 KARP-RABIN 的字符块匹配 32 | 函数名: STRSTR 32 | BM 算法的改进的算法 SUNDAY ALGORITHM 32 | 最短公共祖先(两个长字符串) 33 | 最短公共祖先(多个短字符串) 33 Geometry 计算几何 34 | GRAHAM 求凸包 O(N * LOGN) 34 | 判断线段相交 34 | 求多边形重心 34 | 三角形几个重要的点 34 | 平面最近点对 O(N * LOGN) 34 | LIUCTIC 的计算几何库 35 | 求平面上两点之间的距离 35 | (P1-P0)*(P2-P0)的叉积 35 | 确定两条线段是否相交 35 | 判断点 P 是否在线段 L 上 35 | 判断两个点是否相等 35 | 线段相交判断函数 35 | 判断点 Q 是否在多边形内 35 | 计算多边形的面积 35 | 解二次方程 AX^2+BX+C=0 36 | 计算直线的一般式 AX+BY+C=0 36 | 点到直线距离 36 | 直线与圆的交点,已知直线与圆相交 36 | 点是否在射线的正向 36 | 射线与圆的第一个交点 36 | 求点 P1 关于直线 LN 的对称点 P2 36 | 两直线夹角(弧度) 36 ACM/ICPC 竞赛之 STL 37 ACM/ICPC 竞赛之 STL 简介 37 ACM/ICPC 竞赛之 STL--PAIR 37 ACM/ICPC 竞赛之 STL--VECTOR 37 ACM/ICPC 竞赛之 STL--ITERATOR 简介 38 ACM/ICPC 竞赛之 STL--STRING 38 ACM/ICPC 竞赛之 STL--STACK/QUEUE 38 ACM/ICPC 竞赛之 STL--MAP 40 ACM/ICPC 竞赛之 STL--ALGORITHM 40 STL IN ACM 41 头文件 42 线段树 43 求矩形并的面积(线段树+离散化+扫描线) 43 求矩形并的周长(线段树+离散化+扫描线) 44

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰深入学习计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值