动态规划讲解

整理自牛客网左程云视频课程

例子:

1. 暴力搜索方法



暴力递归会有很多重复计算。

2. 记忆搜索方法


记忆搜索方法算是一种动态规划方法。

3. 动态规划方法


第一列的值都为0,第一行中 aim 值为 arr[0] 整数倍的位置的值是1,其余位置是0。

dp[i][j]的值为以上值的累加,从左到右,从上到下依次填表,最右下角的值即为所求。

求每一个位置都需要枚举,时间复杂度为O(aim),dp 一种有N*aim 个位置,所以总时间复杂度为 O(N *aim^2)。

4.记忆搜索方法与动态规划方法的联系

5.什么是动态规划


因为规定了计算顺序,所以可以利用以前的结果进行优化,去掉枚举过程。

经过化简后时间复杂度为 O(N*aim)。

6.总结

暴力递归题目可以优化成动态规划方法的大体过程:

动态规划方法的关键点:

7.例题

7.1 走完台阶有多少种方法

有 n 级台阶,一个人每次上一级或两级,问有多少种走完 n 级台阶的方法?

递推式:

暴力递归方法:

动态规划:

    public int s1(int n){
        if(n < 1){
            return 0;
        }
        if(n == 1 || n == 2){
            return n;
        }
        int pre = 2;
        int prePre = 1;
        int result = 0;
        for(int i = 3;i <= n;i++){
            result = pre + prePre;
            pre = result;
            prePre = pre;
        }
        return result;
    }

7.2 矩阵中最小路径和


解法:

从左到右,从上到下计算每个位置的值,最后右下角的值即为所求。

7.3 数组最长递增子序列长度


解法:


求 dp[2] 的值:找 arr[2] 左边比它小的数, 哪个 dp 值最大,将其作为倒数第二个数。


所以状态方程为:

如果左边没有比 arr[i] 小的数,那么 dp[i]=1。

7.4 两个字符串的最长公共子序列


解法:

7.5 背包问题


解法:

7.6 将 str1 编辑成 str2 的最小代价


解法:


以上四种可能的值中,选最小值作为 dp[i][j] 的值。
最终结果返回 dp 最右下角的值。

附:
另一篇关于动态规划不错的博客 https://blog.csdn.net/u013309870/article/details/75193592

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务