01背包
有约束条件,背包的元素不可以重复使用,值唯一,是01背包问题,可写成如下代码
正序遍历物品元素,倒序遍历背包(约束条件)
// 开始 01背包
for(int i = 0; i < nums.size(); i++) {
for(int j = target; j >= nums[i]; j--) { // 每一个元素一定是不可重复放入,所以从大到小遍历
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
完全背包
指的是每种物品有无限个,背包的元素可以重复使用。
如果是求组合数,即不考虑元素的排列顺序,那么可以写成如下代码,先正序遍历物品元素,再正序遍历背包元素。
for (int i = 0; i < coins.size(); i++) { // 遍历物品
for (int j = coins[i]; j <= amount; j++) { // 遍历背包
if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值则跳过
dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
}
}
如果是完全背包问题求排列数,即考虑元素的排列顺序,那么,需要正序遍历背包元素(约束条件),再正序遍历物品元素,如下代码所示:
for (int i = 0; i <= target; i++) { // 遍历背包
for (int j = 0; j < nums.size(); j++) { // 遍历物品
if (i - nums[j] >= 0 && dp[i] < INT_MAX - dp[i - nums[j]]) {
dp[i] += dp[i - nums[j]];
}
}
}