01背包问题 (动态规划算法)

P01: 01背包问题

题目
给定 N 种物品和一个容量为 V 的背包,物品 i 的体积是 wi,其价值为 ci
(每种物品只有一个)
问:如何选择装入背包的物品,使得装入背包中的物品的总价值最大?算法

面对每一个物品,咱们只有选择放入或者不放入两种选择,每种物品只能放入一次。数组

咱们用以前一样的思路来走一遍试试
假设只剩下最后一件物品,咱们有两种选择
1.剩余空间足够时,选择放入
2.剩余空间不足时,不放入spa

因此咱们有两个最优的子结构:
1.容量为V的背包放入i-1件物品的最优选择
2.容量为V-w[i]的背包放入i-1件物品的最优选择递归

因此,综合起来就是:
i 件物品放入容量为V的背包的最优选择:
max(容量为V的背包放入i-1件物品的最优选择,容量为V-w[i]的背包放入i-1件物品的最优选择+c[i])图片

咱们用f[i] [v]表示前 i 件物品放入容量为 v 的背包中能够得到的最大价值。
用子问题定义状态:
其状态转移方程是:f[i] [v] = max{f[i-1] [v],f[i-1] [v-w[i]]+c[i]}ci

咱们先假设
背包总容量为V = 12
物品的容量数组为 w = [4, 6, 2, 2, 5, 1]
价值数组为 c = [8, 10, 6, 3, 7, 2]it

  1. f(i,v) = 0 (i<=1, v<w[0]);
  2. f(i,v) = c[0] (i==1, v>=p[0]);
  3. f(i,v) = f(i-1,v) (i>1, v<w[i-1])
  4. f(i,v) = max(f(i-1,v), f(i-1,v-w[i-1])+c[i-1])(i>1, v>=w[i-1])

图片描述

咱们每次从左至右,保存前一次的数据
从上至下时,保存前一行的数据
因此咱们总的来讲只用保存一行的数据,空间复杂度为O(V)
时间复杂度为O(N*V),空间复杂度为O(V);class

可是,若是咱们用原始的递归办法去作,即排列组合的方法去作时
时间复杂度为O(2^N);方法

那么当V很大,N较小时,好比V=1000,N=6时,用递归只用计算2^6=64次,而备受推崇的动态规划就须要计算1000*6=6000次im

因此说,算法没有绝对的好坏,关键要看应用的惨景

相关文章
相关标签/搜索