背包问题是一个非常典型的考察动态规划应用的题目,对其加上不同的限制和条件,可以衍生出诸多变种,若要全面理解动态规划,就必须对背包问题了如指掌。

01背包问题

题目描述

一个小偷面前有一堆(n个)财宝,每个财宝有重量w和价值v两种属性,而他的背包总容量为m如何选取财宝,可以取得最大价值

  • 01:即限定每个物品要么拿(1个)要么不拿(0个)。

状态转移方程如下:
背包问题 - 图1

  • 背包问题 - 图2:表示背包大小为i的情况下能选取的财宝的最大价值;
  • 背包问题 - 图3:背包容量;
  • 背包问题 - 图4:当前财宝的价值;
  • 背包问题 - 图5:当前财宝的重量;

    dp示例

  1. for w, v in n:
  2. # 此处不能从前往后遍历背包,
  3. # 因为从前往后的话,可能导致同一个财宝被放入背包多次
  4. for i in range(m, w - 1, -1):
  5. dp[i] = max(dp[i], v + dp[i - w])

leetcode 题目1

语雀内容

leetcode 题目2

语雀内容

完全背包问题

如果每个财宝可以无限选用,则该问题称为完全背包问题。

动态转移方程如下:
背包问题 - 图6

dp示例

  1. for w, v in n:
  2. for i in range(w, m + 1): # 注意这一行,从前往后遍历
  3. dp[i] = max(dp[i], v + dp[i - w])

leetcode 题目

语雀内容

多重背包问题

如果限定财宝**i**最多只能拿**k**,则问题称为有界或多重背包问题。

动态转移方程如下:
背包问题 - 图7

dp示例

  1. for w, v in n:
  2. for i in range(m, w - 1, -1):
  3. for k in range(k + 1):
  4. dp[i] = max(dp[i], k*v + dp[i - k*w])