《背包九讲》学习笔记(未完待续)
1. 01 背包问题
描述
n
个物品放进容量为
核心代码
///dp[j]为前i个物品装在容量为j的背包内可以产生的最大总价值
int dp[v + 1] = {0};
for(int i = 0; i < n; ++i) {
for(int j = v; j >= c[i]; --j) {
///对于每个物品i,对于容量j,判断是否从容量j-c[i]的背包加上一个i物品转移来更优
dp[j] = max(dp[j],dp[j - c[i]] + w[i]);
}
}
复杂度
- 时间复杂度
O(vn) - 空间复杂度
O(v)
例题
待续
备注
初始化:
- 当不要求全部装满背包时,全部初始化为0
- 当要求全部装满背包时,dp[0]初始化为0,其余的初始化为-INF
- 各类背包可参照该初始化技巧
与完全背包在写法上的区别:
-
j
从
v 递减到 ci ,因为每次只会访问下标比j小的dp值,故这样可以保证每种物品最多被取一次
2. 完全背包问题
描述
n
种物品各无限个放进容量为
核心代码
///dp[j]为前i种物品装在容量为j的背包内可以产生的最大总价值
int dp[v + 1] = {0};
for(int i = 0; i < n; ++i) {
for(int j = c[i]; j <= v; ++j) {
///对于每个物品i,对于容量j,判断是否从容量j-c[i]的背包加上一个i物品转移来更优
dp[j] = max(dp[j],dp[j - c[i]] + w[i]);
}
}
复杂度
- 时间复杂度
O(vn) - 空间复杂度
O(v)
例题
备注
与01背包在写法上的区别:
-
j
从
ci 递增到 v <script type="math/tex" id="MathJax-Element-20">v</script>,当访问下标比j小的dp值时,该值可能是已经加入了物品i而产生的,故这样可以使每种物品被取多次