其他分享
首页 > 其他分享> > 动态规划详解

动态规划详解

作者:互联网

一、名词解释

动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题最短路径问题和复杂系统可靠性问题等中取得了显著的效果  。(引自百度百科)

动态规划最核心的思想,就在于拆分子问题,记住过往,减少重复计算

二、举例说明

LeetCode的题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。

解析:

要想跳到第10级台阶,要么是先跳到第9级,然后再跳1级台阶上去;要么是先跳到第8级,然后一次迈2级台阶上去。

要想跳到第9级台阶,要么是先跳到第8级,然后再跳1级台阶上去;要么是先跳到第7级,然后一次迈2级台阶上去。

...

要想跳到第2级台阶,要么是先跳到第1级,然后再跳1级台阶上去;要么是一次迈2级台阶上去。

要想跳到第1级台阶,一次迈1级台阶上去。

依此类推:

f(10) = f(9)+f(8)

f (9)  = f(8) + f(7)

f (8)  = f(7) + f(6)
...

f (2)  = 2

f (1)  = 1

此时可以用递归的方式:

class Solution {
    public int numWays(int n) {
    if(n == 1){
        return 1;
    }
     if(n == 2){
        return 2;
    }
    return numWays(n-1) + numWays(n-2);
    }
}

但是这样会有大量的重复计算,我们可以进行优化一下,把一些重复的进行缓存。空间复杂度是O(n)。

public class Solution {
    //使用map缓存
    Map<Integer, Integer> tempMap = new HashMap();
    public int numWays(int n) {
        if (n == 0) {
            return 1;
        }
        if (n <= 2) {
            return n;
        }
        if (tempMap.containsKey(n)) {
            return tempMap.get(n);
        } else {
            tempMap.put(n, (numWays(n - 1) + numWays(n - 2)));
            return tempMap.get(n);
        }
    }
}

上面是自上而下的递归结合map起到缓存的作用,用动态规划就是自下而上进行计算。空间复杂度是O(1)。

public class Solution {
    public int numWays(int n) {
        if (n<= 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        int a = 1;
        int b = 2;
        int temp = 0;
        for (int i = 3; i <= n; i++) {
            temp = a + b;
            a = b;
            b = temp;
        }
        return temp;
    }
}

总结:

1.首先可以用穷举法进行分析

2.找出特殊的跳法(边界值)

3.找出规律,确定最优子结构

4.写出伪代码,进行实现

使用场景:

如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划,

比如一些求最值的场景,如最长递增子序列、最小编辑距离、背包问题、凑零钱问题等等,都是动态规划的经典应用场景。

标签:numWays,台阶,int,要么,详解,动态,规划,public
来源: https://blog.csdn.net/qq382495414/article/details/116700632