【Weekly Algorithm】算法周记之《代码随想录》动态规划(三)
学习小结
本周跟随《代码随想录》继续推进动态规划的相关学习,主要是完全背包的入门,体会其与 01 背包的不同与关联。
下周两门考试,教务脑子真是进了水,搞这么紧干嘛。
动态规划
完全背包理论
题目,与 [[01背包理论]]的差别在于一个物品可携带多次,求最大价值
方法,
- dp[j],在遍历物品时,截止到空间为 j,可装入的最大价值
- 递推公式,dp[j]=max(dp[j],dp[j-weigh[i]]+val[i])
- 初始化,全 0
- 遍历方向,重点,这是与 01 背包区别最大的地方,01 的滚动数组强调倒序遍历就是为了避免重复,在完全背包中,恰恰需要正序从而利用重复装入物品
- 举例,……
参考代码随想录思路的解法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, v;
cin >> n >> v;
vector<int> weigh;
vector<int> val;
// 初始化输入
for (int i = 0; i < n; i++) {
int tmp_w, tmp_v;
cin >> tmp_w >> tmp_v;
weigh.push_back(tmp_w);
val.push_back(tmp_v);
}
vector<int> dp(v+1, 0);
for (int i = 0; i < n; i++) {
for (int j = weigh[i]; j <= v; j++) {
dp[j] = max(dp[j], dp[j-weigh[i]]+val[i]);
}
}
cout << dp[v] << endl;
return 0;
}零钱兑换II
题意,给硬币面额和目标面额,求凑出目标面额的硬币组合数( 122 和 221 算重复组合)
方法,
- dp[j] 是在目标面额为 j 时,组合数
- 递推公式,dp[j] += dp[j-coin[i]];
- 初始化,由于递推公式,决定了 dp[0]=1
- 遍历方向,这是重点,不可颠倒,求组合数就要先遍历硬币面额,后遍历目标面额;求排列数就要先遍历目标面额,后遍历硬币面额;可以这么理解,先遍历硬币面额,就可以让后面 dp[j] 的硬币大小顺序固定,不会出现 221 这种情况。
- 举例……
参考代码随想录思路的解法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount+1, 0); // dp[j] 代表考虑前i种硬币,可以凑出多少种组合
dp[0] = 1;
for (int i = 0; i < coins.size(); i++) {
for (int j = coins[i]; j < amount+1; j++) {
if (dp[j] < INT_MAX - dp[j-coins[i]])
dp[j] += dp[j-coins[i]];
}
}
return dp[amount];
}
};组合总和IV
题意,有一个整数数组与一个目标整数,求整数数组中和为目标数的排列数,其值必为 int 范围内
方法,与[[零钱兑换II]]相似,不同的是,求排列数需要先遍历背包容量,再遍历物品,才能达到取到乱序的效果
陆爻齐试探出的解法,与代码随想录思路相近
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
// dp[j] 即在目标为 j 时,元素组合个数
vector<int> dp(target+1, 0);
dp[0] = 1;
for (int j = 0; j < target+1; j++) {
for (int i = 0; i < nums.size(); i++) {
if (j >= nums[i] && dp[j] < INT_MAX - dp[j-nums[i]]) dp[j] += dp[j-nums[i]];
}
}
return dp[target];
}
};
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LuYaoQi's Blogs!