贪心 穷举 动态规划 区别

 

咱们面对的是一个求最优解或统计之类的问题,这个问题基于“咱们要模拟完成一个大任务”,这个大任务能够分红若干步骤,每一个步骤有若干种决策,每一个步骤完成后,就到达了一个阶段性状态
好比,你要从A地到Z地,没有直达,因此第一步须要到一个中间地点,好比H或I,第二步再前进,好比到P或Q,最后到达Z,每一步有若干决策,好比第一步你能够决定到H或I的中的某个,大体就是这样一个模型,能够本身画个地图看看
等等,你大概发现问题了,若是第一步到H和I均可以,第二步到P和Q均可以,那我每一步只选最优,不就用贪心获得结果了吗,没错,若是你须要经历的每一个阶段状态跟决策无关,那就贪心获得结果好了,理解贪心了吗:)算法


然而现实状况多是,你第一步的选择会影响后面的分支,好比你第一步能够选择到H或I,可是到了H后,你只能选择通过P或Q到Z了,而若是到了I,你只能选择R或S到Z,这样一来,即使第一步到H或I你选择了较好的一条路,也不保证最终结果最优,由于好比你选了H,那万一I-R-Z的路要比H开始到Z的路径短了更多,最优路径多是A-I-R-Z,因此你要把这些路都尝试一遍,才知道哪一个最优,理解穷举了么?:)ide

OK,咱们稍微改下题设,假如从I出发不是到R和S,而是到Q或R,会如何优化

诚然,咱们能够用穷举每条路来解决这个问题,须要穷举的路径数和上面的图同样,可是,咱们能够有更快的办法,你不用将A-H-Q-Z和A-I-Q-Z两条路单独计算,由于他们有状态交点,结合第一张图的思想,能够敏锐地感受到,咱们只须要计算到每一个有共同状态的位置求各阶段的最优,最后每阶段选最优组合贪心组合起来就行,由于各阶段完成的状态点是你们都有的嘛,所以,我们先计算A-H-Q和A-I-Q,选个最好的,而后跟Q到Z中最好的拼起来,就是最优了,不必把全部路径都搞一遍(虽然图里面Q到Z直达,但你能够发挥想象力,将其想象成各类分支的一条复杂道路),这样一来就把一个x^(a+b+c+...)的计算次数下降为x^a+x^b+x^c...,其中x表明每次的决策次数(简单点假设每次决策次数都同样),abc表明每一个阶段的步骤数3d


所以,咱们能够从A开始,向Z进行BFS,并对BFS中每一个点保存最优状态,若是有不一样的路径BFS到了同一个点,留最好的一条就行,好比上面这个,你的算法可能先从A-H-Q搜到了Q这个位置,以后从A-I-Q又到了这里,留最好的一条,最后一轮从PQR三个点到Z,就结束了,相对第二章图要少一次运算blog


若是你理解了,恭喜你已经能有效解决不少须要DP的问题了,同时还学会了解图论的单源最短路径问题呢队列

 

最后用经典的0-1背包问题作个例子,巩固一下吧,这个任务是,咱们从N个物品选若干塞到能够承受最大重量W的包包里面,要价值最大,所以就能够将任务分红N个步骤,每一个步骤面对第i号物品,决策有两条:选,仍是放弃,这里的状态,就是影响以后步骤决策的因素,在这里,就是“背包的剩余空间”it


好比,物品的重量是1,2,3,4,5,6,W=12,从头决策,0表示放弃,1表示选,BFS三次后有8种状态:
000 剩12
001 剩9
……(略)
110 剩9
……(略)
前三次步骤后,001和110到达了一样的状态,都是剩余可装重量9的东西,这样在剩下的决策中,这俩分支走的路都是同样的,跟你以前是选了001仍是110没有任何关系(无后效性),所以只要看001价值大,仍是110价值大就能够了,8个状态减小为7个,继续BFS下去,每一轮都合并一样状态,完成后,从最后一轮的全部状态中,找到价值最大的就ok了class


因为状态最多有W+1个,进行N轮,所以复杂度O(NW),书上说的状态迁移方程的办法其实跟这个过程很相似,不过对于有些题目,比起BFS+状态合并,状态方程的分析能够作更好的优化,如引入单调队列什么的,但BFS+状态合并可让你获得一个没有追求极限可是也比较快的解决方案了,结合具体问题有时候更适合,好比根据问题的实际需求,搜索能够限界剪枝减小工做量,我在工做中就用过,替换了同事从wiki抄的DP算法,效率能提高一些效率

 

做者:冒泡
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
 搜索