经典01背包问题解答推导过程

问题描述

有一个容量为 C 的背包,有 N 个物品,每个物品的重量列表为 weights,价值列表为 values,问可以放入背包的的物品的最大价值是多少。

问题分析

要更好的理解动态规划的解法,就应该从暴力解法出发,因为动态规划本质上就是一种优化后的暴力解法。假设现在我们准备用 dfs 解决这个问题,那么怎么定义 dfs 函数呢?
首先,定义原问题,数组的前 N 个物品,在背包容量为 C 时,把物品装入背包,可以获得的最大价值。从原问题出发,从后向前考虑每一个物品。考虑最后一个物品,此时有两种情况:

  1. 物品容量大于背包容量,显然这个物品无法选择,问题变成数组的前 N - 1 个物品,在背包容量为 C 时,把物品装入背包,可以获得的最大价值。
  2. 物品容量小于等于背包容量,物品可以放入背包。注意,此时我们也有两种选择:放或者不放。假设放进去,问题就变成数组的前 N - 1 个物品,在背包容量为 C - weights[i] 时,把物品装入背包,可以获得的最大价值。假设不放进去,问题就变成数组的前 N - 1 个物品,在背包容量为 C 时,把物品装入背包,可以获得的最大价值。

函数定义

注意此时的情况 2,一旦我们选择放入物品,背包容量就会发生变化,这启发我们,背包容量应该是一个变量,在搜索的过程中,这个值会发生变化。基于以上分析,定义如下 dfs() 函数。

def dfs(i, j):
    if i == -1:
        return 0
    if j < weights[i]:
        return dfs(i - 1, j)
    return max(dfs(i - 1, j), dfs(i - 1, j - weights[i]) + values[i])

下面开始解释代码:

  • dfs(i, j) 表示以下标 i 结尾的物品列表,在背包容量为 j 时,可以放入背包的最大的价值ÿ

你可能感兴趣的:(算法,java)