完全背包理论
- 物品有N件,求取得的最大值,
- 标准的完全背包问题,遍历顺序无所谓,需要取多次,所以从小到大遍历,之前01为了仅取一次从大到小遍历
// 0 1背包核心,一定是先物品再背包容量,需要从大到小
for(int i = 0
for(int j = bagWeight
dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
}
}
// 完全背包,先遍历物品,在遍历背包
void test_CompletePack() {
vector<int> weight = {1, 3, 4}
vector<int> value = {15, 20, 30}
int bagWeight = 4
vector<int> dp(bagWeight + 1, 0)
for(int i = 0
for(int j = weight[i]
dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
}
}
cout << dp[bagWeight] << endl
}
int main() {
test_CompletePack()
}
// 完全背包,先遍历背包,再遍历物品
void test_CompletePack() {
vector<int> weight = {1, 3, 4}
vector<int> value = {15, 20, 30}
int bagWeight = 4
vector<int> dp(bagWeight + 1, 0)
for(int j = 0
for(int i = 0
if (j - weight[i] >= 0) dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
}
}
cout << dp[bagWeight] << endl
}
int main() {
test_CompletePack()
}
心得
题解
- 完全背包中一维数组遍历顺序没有影响,但是本题求得是方法,是组合,组合问题对于遍历顺序有要求,必须物品在前,保证,装满背包的方法递推公式都是dp[j] += dp[j - weight[i]];
- 背包在前的话,是排列问题,对于本题不适用
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount + 1, 0);
dp[0] = 1;
for (int i = 0; i < coins.size(); i++) {
for (int j = coins[i]; j <= amount; j++) {
dp[j] += dp[j - coins[i]];
cout << "硬币" << coins[i] << "容量为" << j << "时的种类" << dp[j] << endl;
}
}
return dp[amount];
}
};
心得
题解
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1, 0)
dp[0] = 1
// dp[1] = 1
for (int j = 0
for (int i = 0
if (j - nums[i] >= 0 && dp[j] < INT_MAX - dp[j - nums[i]]) dp[j] += dp[j - nums[i]]
}
}
return dp[target]
}
}