知识点总结:背包问题(0/1 背包)
问题描述:给定一个背包的容量 T
和 M
种物品,每种物品具有体积 x
和价值 y
。在不超过背包容量 T
的前提下,选择若干物品,使得总价值最大化。
1. 动态规划状态说明(DP状态说明)
在这个背包问题中,我们使用动态规划来求解。
- 状态定义:定义
dp[j]
表示背包容量为j
时能够得到的最大价值。 - 初始状态:
dp[0] = 0
,表示当背包容量为 0 时,没有物品可以放入,价值为 0。
2. 递推公式
在处理每件物品时,我们有两个选择:
- 不选这件物品,则当前背包容量
j
的最大价值仍然是dp[j]
。 - 选这件物品,则最大价值变为
dp[j - x] + y
(前一个容量为j - x
的最大价值,加上当前物品的价值)。
因此,递推公式为:
[
dp[j] = \max(dp[j], dp[j - x] + y)
]
逆序遍历:为了确保每个物品在每次选择中只被使用一次,我们在容量从大到小的顺序进行遍历,以免重复计算一个物品的价值。
3. 代码实现
根据上述思路,代码实现如下:
#include <bits/stdc++.h>using namespace std;const int N = 1e4;
int dp[N];int main()
{int T, M;cin >> T >> M;int x, y;// 遍历每种物品for (int i = 0; i < M; i++){cin >> x >> y;// 逆序遍历容量,防止重复使用物品for (int j = T; j >= x; j--){dp[j] = max(dp[j], dp[j - x] + y); // 递推公式:取最大值}}cout << dp[T]; // 输出容量为 T 时的最大价值return 0;
}
- 输入部分:读取背包容量
T
和物品数量M
,以及每件物品的体积x
和价值y
。 - 动态规划填表:对于每件物品
x
和y
,通过逆序遍历j
更新dp[j]
的值,确保背包容量j
时获得的最大价值。 - 输出结果:
dp[T]
即为在给定容量T
时背包能够达到的最大总价值。