动态规划特辑-01-基础篇

发布时间:2022-07-04 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了动态规划特辑-01-基础篇脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

动态规划特辑-01

一、动态规划的题目特点

1、计数

  • 有多少种方法走到右下角
  • 有多少种方法选出k个数使得和为sum

2、求最大值最小值

  • 从左上角走到右下角路径的最大数字和
  • 最长上升子序列长度

3、求存在性

  • 取石子游戏,先手是否必胜
  • 能不能取出k个数使得和是sum

二、求最值型动态规划——案例讲解解题步骤

1、问题描述---求最大最小值的动态规划

动态规划特辑-01-基础篇

2、动态规划组成部分一:确定状态

  • 简单的说,解决动态规划问题的时候需要开一个数组,不管是几维的数组,我们都要明白数组的每个元素f[i]或者f[i][j]都代表什么。
  • 确定状态需要两个意识:

①最后一步

目的是通过最后一步,把问题转化成子问题。

动态规划特辑-01-基础篇

动态规划特辑-01-基础篇

②子问题

动态规划特辑-01-基础篇

动态规划特辑-01-基础篇

③递归解法

动态规划特辑-01-基础篇

递归解法的问题

动态规划特辑-01-基础篇

f(20重复了3次,递归重复了好多次,等到程序的数量特别庞大的时候,就会造成问题。

3、动态规划组成部分二:转移方程

动态规划特辑-01-基础篇

4、动态规划组成部分三:初始条件和边界情况

初始条件就是把最小的情况定义下来,边界情况就是不要数组越界。

动态规划特辑-01-基础篇

5、动态规划组成部分四:计算顺序

从大到小还是从小到大去计算

动态规划特辑-01-基础篇

顺序演示:

正无穷代表拼不出来

动态规划特辑-01-基础篇

最后,可以算出f[27]要用5枚硬币。

计算次数

由于没有重复的计算,相比于递归,动态规划的速度很快。

动态规划特辑-01-基础篇

6、小结

动态规划特辑-01-基础篇

7、题目练习——lintcode-669.换硬币

①问题描述

动态规划特辑-01-基础篇

动态规划特辑-01-基础篇

②代码解决

需要注意的点:

  • 数组开辟的大小
  • 初始化f[0]
  • f[i]的处理,Integer的最大值
  • 转移方程
public class Solution {
    /**
     * @param coins: a list of integer
     * @param amount: a total amount of money amount
     * @return: the fewest number of coins that you need to make up
     */
    public int coinChange(int[] coins, int amount) {
        //开多大的数组呢?amount就是总量
        //如果要用到n,我们就要开辟数组[n+1],因为下标从0开始
        //如果要用到n-1,我们就开辟数组[n]
        int[] f = new int[amount + 1];

        int n = coins.length;//number of kinds of coins

        //inITialization
        f[0] = 0;

        int i,j;
        //f[1] f[2] ... f[27]
        for (i = 1; i <= amount; ++i){
            f[i] = Integer.MAX_VALUE;
            //last coinA[j]
            //f[i] = min{f[i-A[0]]+1,...,f[i-A[n-1]]+1]}
            for (j = 0; j < n; ++j){
                //编程细节的判断,很重要!越界的判断
                if (i >= coins[j] && f[i -coins[j]] != Integer.MAX_VALUE){
                    f[i] = Math.min(f[i - coins[j]]+1, f[i]);
                }
                
            }
        }

        if (f[amount] == Integer.MAX_VALUE){
            f[amount] = -1;
        }

        return f[amount];
    }
}
@H_406_179@

三、计数型动态规划——机器人路径问题

1、题目描述

动态规划特辑-01-基础篇

2、步骤一:确定状态

①最后一步

动态规划特辑-01-基础篇

②子问题

动态规划特辑-01-基础篇

3、步骤二:转移方程

动态规划特辑-01-基础篇

4、步骤三:初始条件和边界情况

动态规划特辑-01-基础篇

5、步骤四:计算顺序

如何确定计算顺序呢?根据转移方程来,在算右下角的格子时候,左面的格子刚刚算得到,上面的格子已经得到。

动态规划特辑-01-基础篇

6、题目练习——lintcode-114.不同的路径

①问题描述

动态规划特辑-01-基础篇

②代码解决

  • 这里把初始化放到了for循环里面,为什么不在外面写呢?因为for循环会把所有格子都遍历一遍,所以直接写到里面就好了。
public class Solution {
    /**
     * @param m: positive integer (1 <= m <= 100)
     * @param n: positive integer (1 <= n <= 100)
     * @return: An integer
     */
    public int uniquePaths(int m, int n) {
        //注意此处为什么之开辟m到n,因为最终的结果只用到[m-1,n-1]
        int[][] f = new int[m][n];
        int i,j;
        for (i=0;i<;m;i++){//row: top to bottom
            for(j=0;j<n;j++){//column: left to right
                if(i==0 || j==0){
                    f[i][j] = 1;
                }else{
                    f[i][j] = f[i-1][j] + f[i][j-1];
                }
            }
        
        }
    return f[m-1][n-1];
    }
}

四、存在型可行性型动态规划——Jump Game

1、题目描述

动态规划特辑-01-基础篇

2、步骤一:确定状态

①最后一步

动态规划特辑-01-基础篇

通过最后一步来确定子问题

②子问题

动态规划特辑-01-基础篇

3、步骤二:转移方程

动态规划特辑-01-基础篇

4、步骤三:初始条件和边界情况

动态规划特辑-01-基础篇

5、步骤四:计算顺序

动态规划特辑-01-基础篇

6、题目练习——lintcode-116.跳跃游戏

①问题描述

@H_961_304@

动态规划特辑-01-基础篇

②代码解决

public class Solution {
    /**
     * @param A: A list of integers
     * @return: A boolean
     */
    public boolean canJump(int[] A) {
        int n = A.length;
        boolean[] f = new boolean[n];
        f[0] = true;//initialization

        for (int j=1;j < n;j++){
            f[j] = false; //假设不能通过
            //previous stone i
            //last jump is From i to j
            for (int i=0; i < j; i++){
                if(f[i] &amp;& i + A[i] >= j){
                    f[j] = true;
                    break;
                }
            }
        }
        return f[n-1];
    }
}

五、后续学习方向

动态规划特辑-01-基础篇

脚本宝典总结

以上是脚本宝典为你收集整理的动态规划特辑-01-基础篇全部内容,希望文章能够帮你解决动态规划特辑-01-基础篇所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。