淘宝的双十一购物节有各种促销活动,比如“满200减20元”,假如你的购物车中有n(>100)个商品,在凑够满减条件的情况下,让选出来的商品价格中和最大程度的接近满减条件,这样就可以极大限度的“薅羊毛”。怎么通过编程来解决这个问题吗?
要想解决这个问题,就要用到我们今天讲的动态规划(Dynamic Programming)。
动态规划比较适合用来求解最优问题,比如求最大值、最小值等。它可以非常显著的降低时间复杂度,提高代码的执行效率。不过,它也是出了名的难学。它的主要学习难点跟递归类似,求解问题的过程不太符合人类常规的思维习惯。对于新手来说,想要入门确实不容易,不过,等你掌握之后,你会发现,实际上并没有想象中那么难。
为了更容易理解动态规划,我分了三节给你讲解,这三节内容分别是,初识动态规划、动态规划理论、动态规划实战。
第一节,我们通过两个非常经典的动态规划问题模型,向你展示为什么需要动态规划,以及动态规划解题方法是如何演化出来的。实际上,你只要掌握了这两个例子的解题思路,其他很多动态规划问题,你都可以套用类似的思路来解决。
第二节,我会总结动态规划适合解决的问题的特征、以及动态规划解题思路。除此之外,我还会将贪心、分治、回朔、动态规划这四种算法思想放在一起,对比分析他们各自的特点以及适用的场景。
第三节,我们教你应用第二节讲的动态规划理论知识,实战解决三个非常经典的动态规划问题,加深你对理论的理解。弄懂了这三个例子,对于动态规划这个知识点,你就算入门了。
我在将贪心算法、回溯算法的时候,多次降到背包问题,今天,我们依旧那这个问题来举例。
对于一组不同重量、不可分割的物品,我们需要选择一些装入背包,在满足背包最大重量限制的情况下,背包中物品中重量的最大值是多少呢?
关于这个问题,我们上一节讲了回溯算法的解决方法,也就是穷举搜索所有可能的解法,然后找出满足条件的最大值。不过,回溯算法的复杂度比较高,是指数级别的。那有没有什么规律,可以有效降低时间复杂度呢?我们一起来看看。