力扣刷题记录2

动态规划之背包问题

参考链接:动态规划之背包问题系列

百度百科有云:背包问题(Knapsack problem)是一种组合优化的NP完全(NP-Complete,NPC)问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?

NPC问题是没有多项式时间复杂度的解法的,但是利用动态规划,我们可以以伪多项式时间复杂度求解背包问题。一般来讲,背包问题有以下几种分类:

1. 0-1背包问题

1.1 题目

最基本的背包问题就是0-1背包问题(01 knapsack problem):一共有N件物品,第i(i从1开始)件物品的重量为w[i],价值为v[i]。在总重量不超过背包承载上限W的情况下,能够装入背包的最大价值是多少?

1.2 分析

如果采用暴力穷举的方式,每件物品都存在装入和不装入两种情况,所以总的时间复杂度是O(2^N),这是不可接受的。而使用动态规划可以将复杂度降至O(NW)。我们的目标是书包内物品的总价值,而变量是物品和书包的限重,所以我们可定义状态dp:
d p [ i ] [ j ] 表 示 将 前 i 件 物 品 装 进 限 重 为 j 的 背 包 可 以 获 得 的 最 大 价 值 , 0 < = i < = N , 0 < = j < = W dp[i][j]表示将前i件物品装进限重为j的背包可以获得的最大价值, 0<=i<=N, 0<=j<=W dp[i][j]ij,0<=i<=N,0<=j<=W

那么我们可以将 d p [ 0 ] [ 0... W ] dp[0][0...W] dp[0][0...W]初始化为0,表示将前0个物品(即没有物品)装入书包的最大价值为0。那么当 i > 0 时 d p [ i ] [ j ] dp[i][j] dp[i][j]有两种情况:
不装入第i件物品,即 d p [ i − 1 ] [ j ] dp[i−1][j] dp[i1][j]
装入第i件物品(前提是能装下),即 d p [ i − 1 ] [ j − w [ i ] ] + v [ i ] dp[i−1][j−w[i]] + v[i] dp[i1][jw[i]]+v[i]
即状态转移方程为
d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − w [ i ] ] + v [ i ] ) / / j > = w [ i ] dp[i][j] = max(dp[i−1][j], dp[i−1][j−w[i]]+v[i]) // j >= w[i] dp[i][j]=max(dp[i1][j],dp[i1][jw[i]]+v[i])//j>=w[i]
由上述状态转移方程可知, d p [ i ] [ j ] dp[i][j] dp[i][j]的值只与 d p [ i − 1 ] [ 0 , . . . , j − 1 ] dp[i-1][0,...,j-1] dp[i1][0,...,j1]有关,所以我们可以采用动态规划常用的方法(滚动数组)对空间进行优化(即去掉dp的第一维)。需要注意的是,为了防止上一层循环的 d p [ 0 , . . . , j − 1 ] dp[0,...,j-1] dp[0,...,j1]被覆盖,循环的时候 j 只能逆向枚举(空间优化前没有这个限制),伪代码为:

/ / 0 − 1 背 包 问 题 伪 代 码 ( 空 间 优 化 版 ) d p [ 0 , . . . , W ] = 0 f o r   i = 1 , . . . , N        f o r   j = W , . . . , w [ i ] / / 必 须 逆 向 枚 举 ! ! !               d p [ j ] = m a x ( d p [ j ] , d p [ j − w [ i ] ] + v [ i ] ) //0-1背包问题伪代码(空间优化版) \\ dp[0,...,W] = 0\\ for \ i = 1,...,N\\ \ \ \ \ \ \ for \ j = W,...,w[i] // 必须逆向枚举!!!\\ \ \ \ \ \ \ \ \ \ \ \ \ \ dp[j] = max(dp[j], dp[j−w[i]]+v[i]) //01()dp[0,...,W]=0for i=1,...,N      for j=W,...,w[i]//!!!             dp[j]=max(dp[j],dp[jw[i]]+v[i])

时间复杂度为O(NW), 空间复杂度为O(W)。由于W的值是W的位数的幂,所以这个时间复杂度是伪多项式时间。

动态规划的核心思想避免重复计算在0-1背包问题中体现得淋漓尽致。第i件物品装入或者不装入而获得的最大价值完全可以由前面i-1件物品的最大价值决定,暴力枚举忽略了这个事实。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值