背包问题01:一个背包引发血案

连续背包问题:

      还是先讲一段故事吧。假如你是一个贼,有一天你去地主家偷东西。有4斤金沙,2斤银沙,10斤铜沙。

但是运气不好的是,你的包只能装8斤东西。那么你该偷什么走呢?

我们这边把这个问题分解成 方程式和约束条件

方程式:gx + sy + cz --->max #gsc分布代表金银铜

约束条件:x+y+z = 8

     g>s>z

       max(g)=4 max(s)=4 max(c)=4

这里这个问题,是贪心算法的主场,当然有很多解决问题的方法,我们的目的就是找到最优秀的解,我们先保证装足够多的金子,然后如果金子装完了,

而且还有剩余空间的话,就装足够多的银子。。。。在连续问题里,贪心算法的确可以得到最优解,贪心算法的核心就是就是保证局部的优越性,、

但是保证局部的优越性,并不能保证整体的优越性。我们这边先不深入说贪心算法。我们接着说背包问题。

0/1背包问题:

有一个包和n个物品,包的容量为m,每个物品都有各自的体积和价值,问当从这n个物品中选择多个物品放在包里而物品体积总数不超过包的容量m时,能够得到的最大价值是多少?[对于每个物品不可以取多次,最多只能取一次,之所以叫做01背包,0表示不取,1表示取]

这里我们当然可以用贪心算法,和穷举算法,

但是它们都有一个致命的缺点 贪心算法:往往得不到最优解 穷举花费的时间又太多了{指数级别}

这里就需要一个新的算法了---》动态规划(dynamic programming)--->本质上它是对穷举算法的优化

动态规则:首先不要通过他的名字去理解它,它只是一个名字而已,呵呵

好累呀、、、、要不要先休息一会。

我们先谈论子结构的问题吧

def fib(n):
    global numCails
    numCails +=1
    print "numCails-->",numCails
    print "n---->",n
    if n <=1:
        return n
    else:
        return fib(n-1) + fib(n-2)

  我们先看这段代码,如果我传了fib(5). 他会递归 n-1 n-2 然后接着。

这段代码的问题就是,他有很多重复的子结构

这个是fib(5)的输出,你可以看到他有很多相同的子结构

numCails--> 1
n----> 5
numCails--> 2
n----> 4
numCails--> 3
n----> 3
numCails--> 4
n----> 2
numCails--> 5
n----> 1
numCails--> 6
n----> 0
numCails--> 7
n----> 1
numCails--> 8
n----> 2
numCails--> 9
n----> 1
numCails--> 10
n----> 0
numCails--> 11
n----> 3
numCails--> 12
n----> 2
numCails--> 13
n----> 1
numCails--> 14
n----> 0
numCails--> 15
n----> 1

那么dp是如何解决的呢? 

我们先看下图 我们要从A-F

 一共有多少中方案呢?

这个是一个很简单的问题 但是不知道你有没有关注到D 这个重合节点的。

而dp的核心就是寻找最优子结构,说白了就是没有重合的子结构。

http://www.cnblogs.com/nerdlerss/p/5645552.html 

{未完待续}

原文地址:https://www.cnblogs.com/nerdlerss/p/5642205.html