DP问题概述

DP路径问题

  1. DP的关键问题在于寻找整个问题当中是否存在(初始状态,转移状态,状态转移方程)等等关键的key,当我们能够寻找到这些key的时候,那么本问题也能够用dp解决。
  2. DP关键在于找到状态转移方程(重中之重)。

路径的回溯问题

  1. 路径的回溯问题的关键在于能够将回来时的每一步都“记录在案”,然后逆序输出出来,这个问题的解析在点这里。DP路径还涉及到一些跟图算法相关的知识,相关的牵连在上面的链接里面也能够看得到。
  2. dp问题当中的三角路径最短问题,重要的是找到:(状态初始值,转移状态,状态方程)。确定问题前后之间满足”无后效性“的客观定义,使用dp解决问题,空间大小使用滚动数组节省空间。
  3. dp路径的问题最初的demo应该是“一个起点,一个终点”,这个是最简单的模型,再到后面延伸复杂的问题应该包含以下几个方面:

1.一个出发点,多个终点的情况(也就是到达最后一个行或者最后一列的情况),三角路径问题和自顶向下一个终点的问题的变种。
2.多个出发点,多个终点的情况,也就是下降路径问题,一般的解决方案会比之前的一个起点,多个终点的方案多一个空间维度,所以它的空间复杂度在\(O(n^3)\)。可以借助滚动数组方案进行优化工作。空间复杂度一般会降低一个维度。

class Solution {
    int MAX = Integer.MAX_VALUE;
    public int minFallingPathSum(int[][] mat) {
        int n = mat.length;
        int[][] f = new int[n][n];
        // 初始化:对于首行而言,每个位置的「最小成本」就是其「矩阵值」
        for (int i = 0; i < n; i++) f[0][i] = mat[0][i];
        // 从第二行开始,根据题目给定的条件进行转移
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int val = mat[i][j];
                f[i][j] = f[i - 1][j] + val;
                if (j - 1 >= 0) f[i][j] = Math.min(f[i][j], f[i-1][j-1] + val);
                if (j + 1 <  n) f[i][j] = Math.min(f[i][j], f[i-1][j+1] + val);
            }
        }
        int ans = MAX;
        for (int i = 0; i < n; i++) ans = Math.min(ans, f[n-1][i]);
        return ans;
    }
}
posted @ 2022-11-01 11:19  Marvel_Iron_Man  阅读(109)  评论(0编辑  收藏  举报