深入浅出之背包算法——动态规划是如何打败递归的?

背包问题(Knapsackproblem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。这个问题涉及到了两个条件:一是物品总的大小小于或等于背包的大小,二是物品总的价值要尽量大。

一.采用递归的回溯法

刚开始接触此类问题时,很多人都会想到用回溯法解决,也就是用递归,这是最直接的方法,同八皇后、迷宫、组合、全排列、贪吃蛇等问题一样,下面给我本人开始用递归写出的算法:

基本原理很简单:求出满足总量的所有组合,再找出总价值最大的那个组合!

递归算法虽然方便,但是所需时间复杂度很高。该算法的时间复杂度为O(n2^n)


二.动态规划


动态规划方法建立在最优原则的基础上,是用空间换时间的一种方法的抽象。其关键是发现子问题和记录其结果。然后利用这些

结果减轻运算量。


如果我们用子问题定义状态来描述的话可以这样解释

f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。用公式表示:


f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}


具体的解释可以理解为将前i件物品放入容量为v的背包中,只考虑第i件物品的策略(放或不放),那么就可以转化为一个只涉及前i-1件物品和第i件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。v表示背包的最大容量,c[i]表示第i件物品的大小,w[i]表示第i件物品的价值)




你可能感兴趣的:(动态规划)