前言

时隔这么久才发了这篇早在三周前就应该发出来的课堂笔记,由于懒癌犯了,加上各种原因,实在是应该反思。好多课堂上老师说的重要的东西可能细节上有一些急记不住了,但是幸好做了一些笔记,还能够让自己回想起来。动态规划算是我的一道大坎了,本科的时候就基本没有学过,研一的时候老师上课也是吃力的跟上了老师的步伐,其实那个时候老师总结的还是挺好的:把动态规划的题目都分成了一维动规、二维遍历、二维不遍历等一系列的问题。这次听了老师的课程,觉得还是需要更加集中的去把各种题进行一个分类吧,然后有针对的去准备,虽然据说这一块在面试中也不容易考到,但是毕竟是难点,还是需要好好准备一下的。因为在dp这个方面,我算是一个比较新手的新手,所以大家可以当作一起入门内容来看这篇博客。

 

Outline:

  • 了解动态规划
    • Triangle
  • 动态规划的适用范围
  • 坐标型动态规划
    • Minimum Path Sum
    • Climbing Stairs
    • Jump Game
    • Longest Increasing Subsequence
  • 单序列动态规划

    • Word Break
  • 双序列动态规划
    • Longest Common Subsequence
  • 总结

 

课堂笔记

 


1.了解动态规划

就不过多的做解释了,直接来一个经典的题目。

给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。

样例

比如,给出下列数字三角形:

[

     [2],

    [3,4],

   [6,5,7],

  [4,1,8,3]

]

从顶到底部的最小路径和为11 ( 2 + 3 + 5 + 1 = 11)。

拿到这个题目,如果不知道动态规划的话,想必大家第一反应就是遍历全部的路径,然后求出最小的值就可以。这个想法的话,跟二叉树的遍历有一点类似,但是大体还是不一样的,因为二叉树在分岔以后就各自保留子树,而这个题的不能考虑为二叉树的情况,这个结构可以画成如下的情况比较直观:

 [2],

 [3,4],

 [6,5,7],

 [4,1,8,3]

其中,2只能移动到3、4,3只能移动到6、5,同理,5只能移动到1,8……所以总结下来就是:当前的元素只能移动到下方和右下方的元素,即(i,j)只能移动到(i+1,j)或(i+1,j+1)。这样的话,DFS来做搜索就好了。

    int bestans = INT_MAX;
    void travers(int i, int j, int sum, vector<vector<int> > &triangle) {
        if (i == triangle.size()) {
            // 遍历到最底层
            bestans = bestans > sum ? sum : bestans;
            return;
        }
        travers(i + 1, j, sum + triangle[i][j], triangle);
        travers(i + 1, j + 1, sum + triangle[i][j], triangle);
    }
    int minimumTotal(vector<vector<int> > &triangle) {
        // write your code here
        travers(0, 0, 0, triangle);
        return bestans;
    }
View Code

相关文章:

  • 2021-10-11
  • 2021-10-08
  • 2021-07-08
  • 2022-12-23
  • 2022-12-23
  • 2021-12-28
  • 2021-07-05
  • 2021-10-10
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-21
  • 2021-12-27
  • 2021-11-01
  • 2021-12-19
相关资源
相似解决方案