返回

纵横驰骋背包难题,动态规划的制胜之道

前端

踏入算法学习的殿堂,我很快遇到了动态规划这块瑰宝。然而,背包问题就像一道道迷宫,刚开始时让我晕头转向,稍有改动便不知所措。虽然解题方法大同小异,但细微变化却足以让我陷入困境。

在探索背包问题的过程中,我总结了几种常用的解题思路,它们宛如一把把钥匙,开启了通往解决方案的大门。

01. 0-1 背包:二进制的抉择

0-1 背包问题是最基本也是最经典的背包问题。它有一个容量有限的背包和一系列物品,每个物品都有自己的重量和价值。问题是要选择哪些物品放入背包,使背包的总价值最大,同时不超过背包的容量。

解决 0-1 背包问题,最直观的思路是穷举法,即尝试所有可能的物品组合。然而,这种方法效率低下,尤其是当物品数量较多时。于是,动态规划登场了。

动态规划的思想是将问题分解成一系列子问题,然后逐个解决这些子问题,最终得到整体问题的最优解。对于 0-1 背包问题,我们可以将子问题定义为:对于给定的背包容量和物品集合,如何选择物品放入背包,使背包的总价值最大。

我们可以用一个二维数组 dp 来存储子问题的最优解。dp[i][j] 表示当背包容量为 j 时,从前 i 个物品中选择物品放入背包,所能获得的最大价值。

计算 dp[i][j] 的过程如下:

  1. 如果物品 i 的重量大于背包容量 j,则 dp[i][j] 等于 dp[i-1][j],因为无法将物品 i 放入背包。
  2. 否则,dp[i][j] 等于 max(dp[i-1][j], dp[i-1][j - w[i]] + v[i])。其中,w[i] 是物品 i 的重量,v[i] 是物品 i 的价值。

通过以上递推公式,我们可以计算出所有子问题的最优解,最终得到整体问题的最优解。

02. 完全背包:无限供应的物品

完全背包问题与 0-1 背包问题非常相似,唯一的区别是物品可以无限次地放入背包。这意味着我们可以将一件物品放入背包多次,直到背包装满为止。

解决完全背包问题,同样可以使用动态规划的方法。不过,由于物品可以无限次地放入背包,因此我们需要对 0-1 背包问题的递推公式进行一些修改。

修改后的递推公式如下:

dp[i][j] = max(dp[i-1][j], dp[i][j - w[i]] + v[i])

这个公式与 0-1 背包问题的递推公式非常相似,只是少了 dp[i-1][j]这一项。这是因为在完全背包问题中,我们可以将物品 i 多次放入背包,而不仅仅是一次。

03. 分组背包:同类物品的抉择

分组背包问题与 0-1 背包问题和完全背包问题都有相似之处。它也有一个容量有限的背包和一系列物品,每个物品都有自己的重量和价值。不过,分组背包问题中的物品被分成了若干组,每组物品只能选择一件放入背包。

解决分组背包问题,同样可以使用动态规划的方法。不过,我们需要对 0-1 背包问题的递推公式进行一些修改。

修改后的递推公式如下:

dp[i][j] = max(dp[i-1][j], dp[i][j - w[i]] + v[i])

这个公式与 0-1 背包问题的递推公式非常相似,只是多了一个限制条件:物品 i 只能选择一件放入背包。

背包问题是动态规划中非常经典的问题,也是非常重要的基础问题。掌握背包问题的解题思路,可以帮助我们解决许多其他动态规划问题。在本文中,我介绍了 0-1 背包问题、完全背包问题和分组背包问题的解题思路。希望这些思路能够帮助您在解决背包问题时游刃有余。