动态规划

Posted iscanghai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划相关的知识,希望对你有一定的参考价值。

概念:

之前的问题与当前的问题有关联,利用之前问题的答案递推当前问题的答案。

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

题目:

给定三角形:

[
    [2],
   [3,4],
   [6,5,7],
  [4,1,8,3]
]

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11,尝试使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题。)

解题思路:

  • 问题拆解:

    这里的总问题是求出最小的路径和,路径是这里的分析重点,路径是由一个个元素组成的,[i][j] 位置的元素,经过这个元素的路径肯定也会经过 [i - 1][j] 或者 [i - 1][j - 1],因此经过一个元素的路径和可以通过这个元素上面的一个或者两个元素的路径和得到。

  • 状态定义

    状态的定义一般会和问题需要求解的答案联系在一起,这里其实有两种方式,一种是考虑路径从上到下,另外一种是考虑路径从下到上,因为元素的值是不变的,所以路径的方向不同也不会影响最后求得的路径和,如果是从上到下,你会发现,在考虑下面元素的时候,起始元素的路径只会从[i - 1][j] 获得,每行当中的最后一个元素的路径只会从 [i - 1][j - 1] 获得,中间二者都可。

  • 递推方程

    “状态定义” 中我们已经定义好了状态,递推方程就出来了

    dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j]
 1 class Solution {
 2     public int minimumTotal(List<List<Integer>> triangle) {
 3         int n = triangle.size();
 4         int[][] f = new int[n][n];
 5         f[0][0] = triangle.get(0).get(0);
 6         for (int i = 1; i < n; ++i) {
 7             f[i][0] = f[i - 1][0] + triangle.get(i).get(0);//当元素位于最左端的时候
 8             for (int j = 1; j < i; ++j) {//元素位于中间
 9                 f[i][j] = Math.min(f[i - 1][j - 1], f[i - 1][j]) + triangle.get(i).get(j);
10             }
11             f[i][i] = f[i - 1][i - 1] + triangle.get(i).get(i);//元素位于最右
12         }
13         int minTotal = f[n - 1][0];
14         for (int i = 1; i < n; ++i) {
15             minTotal = Math.min(minTotal, f[n - 1][i]);
16         }
17         return minTotal;
18     }
19 }

 

以上是关于动态规划的主要内容,如果未能解决你的问题,请参考以下文章

是否可以动态编译和执行 C# 代码片段?

动态规划_线性动态规划,区间动态规划

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

算法动态规划 ⑤ ( LeetCode 63.不同路径 II | 问题分析 | 动态规划算法设计 | 代码示例 )