请解释什么是背包问题，并给出一个确定性算法解决0/1背包问题。整段回答不得多余500字，且字数不得少于300字。 Sampler应该包括三个部分：问题定义、解决思路、样例代码。解决思路要求三句话以概括。样例代码必须带上注释，且必须使用Python编写的动态规划算法。
user
背包问题是一类组合优化问题，主要分为0/1背包、完全背包和多重背包三种类型。在0/1背包问题中，有N种物品和一个容量为W的背包，每种物品仅有一件，可以选择放入或不放入背包。问如何选择物品，使背包中物品的总价值最大且不超过背包容量。0/1背包问题可以通过动态规划解决，定义状态f[i][j]表示前i个物品放入容量为j的背包能获得的最大价值。解决思路是通过递推关系f[i][j] = max(f[i-1][j], f[i-1][j-weight[i]] + value[i])，计算每个状态的值，最终得到问题的解。下面是使用Python编写的0/1背包问题的动态规划解法样例代码。

```python
def knapsack_01(weights, values, W):
    # weights: 物品重量列表
    # values: 物品价值列表
    # W: 背包的容量
    n = len(weights)  # 物品数量
    # 初始化二维数组dp，dp[i][j]表示前i个物品放满容量为j的背包的最大价值
    dp = [[0] * (W + 1) for _ in range(n + 1)]
    
    # 动态规划求解
    for i in range(1, n + 1):
        for w in range(1, W + 1):
            if weights[i - 1] <= w:
                # 状态转移方程
                dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1])
            else:
                dp[i][w] = dp[i - 1][w]
    
    # 返回最大价值
    return dp[n][W]

# 示例
weights = [1, 3, 4, 5]  # 物品重量
values = [1, 4, 5, 7]  # 物品价值
W = 7  # 背包容量
print(knapsack_01(weights, values, W))  # 输出最大价值
```
以上代码通过定义一个二维动态规划数组，使用两个嵌套循环分别遍历物品和背包容量，根据状态转移方程更新数组值，最终返回问题的解。
assistant