什么是动态规划?

概述


动态规划(Dynamic Programming)是一种分阶段求解决策问题的数学思想,它通过把原问题分解为简单的子问题来解决复杂问题.动态规划在很多领域都有着广泛的应用,例如管理学,经济学,数学,生物学.

动态规划适用于解决带有最优子结构子问题重叠性质的问题.

  • 最优子结构 : 即是局部最优解能够决定全局最优解(也可以认为是问题可以被分解为子问题来解决),如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质.
  • 子问题重叠 : 即是当使用递归进行自顶向下的求解时,每次产生的子问题不总是新的问题,而是已经被重复计算过的问题.动态规划利用了这种性质,使用一个集合将已经计算过的结果放入其中,当再次遇见重复的问题时,只需要从集合中取出对应的结果.

动态规划与分治算法的区别


相信了解过分治算法的同学会发现,动态规划与分治算法很相似,下面我们例举出一些它们的相同之处与不同之处.

相同点

  • 分治算法与动态规划都是将一个复杂问题分解为简单的子问题.
  • 分治算法与动态规划都只能解决带有最优子结构性质的问题.

不同点

  • 分治算法一般都是使用递归自顶向下实现,动态规划使用迭代自底向上实现或带有记忆功能的递归实现.
  • 动态规划解决带有子问题重叠性质的问题效率更加高效.
  • 分治算法分解的子问题是相对独立的.
  • 动态规划分解的子问题是互相带有关联且有重叠的.

斐波那契数列


斐波那契数列就很适合使用动态规划来求解,它在数学上是使用递归来定义的,公式为F(n) = F(n-1) + F(n-2).

斐波那契数列求解过程

普通递归实现

一个最简单的实现如下.

    public int fibonacci(int n) {
        if (n < 1)
            return 0;
        if (n == 1)
            return 1;
        if (n == 2)
            return 2;

        return fibonacci(n - 1) + fibonacci(n - 2);
    }

但这种算法并不高效,它做了很多重复计算,它的时间复杂度为O(2^n).

动态规划递归实现

使用动态规划来将重复计算的结果具有"记忆性",就可以将时间复杂度降低为O(n).

    public int fibonacci(int n) {
        if (n < 1)
            return 0;
        if (n == 1)
            return 1;
        if (n == 2)
            return 2;

        // 判断当前n的结果是否已经被计算,如果map存在n则代表该结果已经计算过了
        if (map.containsKey(n))
            return map.get(n);

        int value = fibonacci(n - 1) + fibonacci(n - 2);
        map.put(n, value);
        return value;
    }

虽然降低了时间复杂度,但需要维护一个集合用于存放计算结果,导致空间复杂度提升了.

动态规划迭代实现

通过观察斐波那契数列的规律,发现n只依赖于前2种状态,所以我们可以自底向上地迭代实现.

    public int fibonacci(int n) {
        if (n < 1)
            return 0;
        if (n == 1)
            return 1;
        if (n == 2)
            return 2;

        // 使用变量a,b来保存上次迭代和上上次迭代的结果
        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;
    }

这样不仅时间复杂度得到了优化,也不需要额外的空间复杂度.

参考资料


本文作者为SylvanasSun(sylvanassun_xtz@163.com),转载请务必指明原文链接.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • 《算法导论》这门课的老师是黄刘生和张曙,两位都是老人家了,代课很慢很没有激情,不过这一章非常有意思。更多见:iii...
    mmmwhy阅读 5,173评论 5 31
  • 下面是王晴儿为大家简单分享的一份医院/医疗医药网站建设制作开发建站解决方案! 一、概述 医院网站的作用更类似于医院...
    设计师王晴儿阅读 977评论 0 50
  • 今天是你的生日,我的花花姐姐。在这个静静地,多情写意的秋里你迎来了61岁生日。 你7岁那年,我们在长航那简陋...
    秋荷浴雨阅读 258评论 0 1
  • 国庆第四天,现在坐在古城的江边,看到的是美景,心情却是复杂的,经过昨天的谈心,我才认识到每个人都是独立的,,而且一...
    清风腾逸阅读 537评论 0 51
  • 土地翻了翻身种子开始按耐不住内心的喜悦 贫穷在田头凝望着远方的城市 田间拿着锄头的老汉擦拭着额头的汗水 土地是幸福...
    心花园子阅读 195评论 0 4