分组背包、完全背包
分组背包:多个物品分组,每组只能取1件。每一组的物品都可能性展开就可以了。时间复杂度 O(物品数量 * 背包容量)
完全背包:与 01 背包的区别仅在于每种商品可以选取无限次。时间复杂度 O(物品数量 * 背包容量)
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| |
| int main() { |
| |
| int m, n; |
| cin >> m >> n; |
| vector<vector<int>> arr(n + 1, vector<int>(3)); |
| for (int i = 1; i <= n; ++i) |
| cin >> arr[i][0] >> arr[i][1] >> arr[i][2]; |
| |
| sort(begin(arr), end(arr), |
| [](vector<int> &v1, vector<int> &v2) { |
| return v1[2] < v2[2]; |
| }); |
| |
| |
| int teams = 1; |
| for (int i = 2; i <= n; ++i) |
| if (arr[i][2] != arr[i - 1][2]) teams++; |
| |
| |
| vector<vector<int>> dp(teams + 1, vector<int>(m + 1)); |
| |
| fill(begin(dp[0]), end(dp[0]), 0); |
| for (int l = 1, r = 2, i = 1; l <= n; ++i) { |
| |
| while (r <= n && arr[l][2] == arr[r][2]) r++; |
| |
| for (int j = 0; j <= m; ++j) { |
| |
| dp[i][j] = dp[i - 1][j]; |
| |
| for (int k = l; k < r; ++k) |
| if (j - arr[k][0] >= 0) |
| dp[i][j] = max(dp[i][j], dp[i - 1][j - arr[k][0]] + arr[k][1]); |
| } |
| |
| l = r++; |
| } |
| cout << dp[teams][m]; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| |
| int main() { |
| |
| int m, n; |
| cin >> m >> n; |
| vector<vector<int>> arr(n + 1, vector<int>(3)); |
| for (int i = 1; i <= n; ++i) |
| cin >> arr[i][0] >> arr[i][1] >> arr[i][2]; |
| |
| sort(begin(arr), end(arr), |
| [](vector<int> &v1, vector<int> &v2) { |
| return v1[2] < v2[2]; |
| }); |
| |
| |
| int teams = 1; |
| for (int i = 2; i <= n; ++i) |
| if (arr[i][2] != arr[i - 1][2]) teams++; |
| |
| |
| |
| vector<int> dp(m + 1, 0); |
| for (int l = 1, r = 2, i = 1; l <= n; ++i) { |
| |
| while (r <= n && arr[l][2] == arr[r][2]) r++; |
| |
| for (int j = m; j >= 0; --j) { |
| |
| for (int k = l; k < r; ++k) |
| if (j - arr[k][0] >= 0) |
| dp[j] = max(dp[j], dp[j - arr[k][0]] + arr[k][1]); |
| } |
| |
| l = r++; |
| } |
| cout << dp[m]; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int maxValueOfCoins(vector<vector<int>> &piles, int m) { |
| |
| int n = piles.size(); |
| |
| vector<vector<int>> dp(n + 1, vector<int>(m + 1)); |
| |
| for (int i = 1; i <= n; ++i) { |
| |
| vector<int> team = piles[i - 1]; |
| |
| int t = min((int) team.size(), m); |
| vector<int> preSum(t + 1); |
| for (int j = 1; j <= t; ++j) |
| preSum[j] = preSum[j - 1] + team[j - 1]; |
| |
| for (int j = 0; j <= m; ++j) { |
| |
| dp[i][j] = dp[i - 1][j]; |
| |
| for (int k = 1; k <= min(t, j); ++k) |
| dp[i][j] = max(dp[i][j], dp[i - 1][j - k] + preSum[k]); |
| } |
| } |
| return dp[n][m]; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int maxValueOfCoins(vector<vector<int>> &piles, int m) { |
| |
| int n = piles.size(); |
| |
| |
| vector<int> dp(m + 1, 0); |
| |
| for (int i = 1; i <= n; ++i) { |
| |
| vector<int> team = piles[i - 1]; |
| |
| int t = min((int) team.size(), m); |
| vector<int> preSum(t + 1); |
| for (int j = 1; j <= t; ++j) |
| preSum[j] = preSum[j - 1] + team[j - 1]; |
| |
| for (int j = m; j >= 0; j--) { |
| |
| |
| for (int k = 1; k <= min(t, j); ++k) |
| dp[j] = max(dp[j], dp[j - k] + preSum[k]); |
| } |
| } |
| return dp[m]; |
| } |
| }; |
完全背包(模版)
给定一个正数 t,表示背包的容量
有 m 种货物,每种货物可以选择任意个
每种货物都有体积 costs[i] 和价值 values[i]
返回在不超过总容量的情况下,怎么挑选货物能达到价值最大
返回最大的价值
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| #define ll long long |
| |
| int main() { |
| int t, m; |
| cin >> t >> m; |
| vector<int> cost(m + 1); |
| vector<int> value(m + 1); |
| for (int i = 1; i <= m; ++i) |
| cin >> cost[i] >> value[i]; |
| |
| |
| vector<vector<ll>> dp(m + 1, vector<ll>(t + 1)); |
| for (int i = 1; i <= m; ++i) { |
| for (int j = 0; j <= t; ++j) { |
| |
| dp[i][j] = dp[i - 1][j]; |
| |
| if (j - cost[i] >= 0) |
| dp[i][j] = max(dp[i][j], dp[i][j - cost[i]] + value[i]); |
| } |
| } |
| cout << dp[m][t]; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| #define ll long long |
| |
| int main() { |
| int t, m; |
| cin >> t >> m; |
| vector<int> cost(m + 1); |
| vector<int> value(m + 1); |
| for (int i = 1; i <= m; ++i) |
| cin >> cost[i] >> value[i]; |
| |
| |
| |
| vector<ll> dp(t + 1, 0); |
| for (int i = 1; i <= m; ++i) { |
| |
| for (int j = cost[i]; j <= t; ++j) { |
| |
| |
| dp[j] = max(dp[j], dp[j - cost[i]] + value[i]); |
| } |
| } |
| cout << dp[t] << endl; |
| } |
| #include <iostream> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| bool recursive(string s, string p, int i, int j) { |
| |
| if (i == s.length()) { |
| |
| if (j == p.length()) return true; |
| |
| |
| return j + 1 < p.length() && p[j + 1] == '*' && recursive(s, p, i, j + 2); |
| } |
| |
| if (j == p.length()) return false; |
| |
| |
| if (j + 1 == p.length() || p[j + 1] != '*') |
| return (s[i] == p[j] || p[j] == '.') && recursive(s, p, i + 1, j + 1); |
| |
| |
| |
| bool p1 = recursive(s, p, i, j + 2); |
| |
| bool p2 = (s[i] == p[j] || p[j] == '.') && recursive(s, p, i + 1, j); |
| return p1 || p2; |
| } |
| |
| bool isMatch(string s, string p) { |
| return recursive(s, p, 0, 0); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| bool recursive(string s, string p, int i, int j, vector<vector<int>> &dp) { |
| if (dp[i][j] != 0) return dp[i][j] == 1; |
| bool res; |
| if (i == s.length()) { |
| |
| |
| if (j == p.length()) { |
| res = true; |
| } else { |
| |
| |
| res = j + 1 < p.length() && p[j + 1] == '*' && recursive(s, p, i, j + 2, dp); |
| } |
| } else if (j == p.length()) { |
| |
| res = false; |
| } else { |
| if (j + 1 == p.length() || p[j + 1] != '*') { |
| |
| |
| return (s[i] == p[j] || p[j] == '.') && recursive(s, p, i + 1, j + 1, dp); |
| } else { |
| |
| |
| |
| bool p1 = recursive(s, p, i, j + 2, dp); |
| |
| bool p2 = (s[i] == p[j] || p[j] == '.') && recursive(s, p, i + 1, j, dp); |
| res = p1 || p2; |
| } |
| } |
| dp[i][j] = res ? 1 : 2; |
| return res; |
| } |
| |
| bool isMatch(string s, string p) { |
| |
| |
| |
| |
| vector<vector<int>> dp(s.size() + 1, vector<int>(p.size() + 1, 0)); |
| return recursive(s, p, 0, 0, dp); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| bool isMatch(string s, string p) { |
| int n = s.length(); |
| int m = p.length(); |
| vector<vector<bool>> dp(s.size() + 1, vector<bool>(p.size() + 1)); |
| dp[n][m] = true; |
| for (int j = m - 1; j >= 0; j--) |
| dp[n][j] = j + 1 < m && p[j + 1] == '*' && dp[n][j + 2]; |
| for (int i = n - 1; i >= 0; i--) { |
| for (int j = m - 1; j >= 0; j--) { |
| if (j + 1 == m || p[j + 1] != '*') { |
| dp[i][j] = (s[i] == p[j] || p[j] == '.') && dp[i + 1][j + 1]; |
| } else { |
| dp[i][j] = dp[i][j + 2] || ((s[i] == p[j] || p[j] == '.') && dp[i + 1][j]); |
| } |
| } |
| } |
| return dp[0][0]; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| |
| class Solution { |
| public: |
| bool recursive(string s, string p, int i, int j) { |
| |
| if (i == s.length()) { |
| |
| if (j == p.length()) return true; |
| |
| |
| return p[j] == '*' && recursive(s, p, i, j + 1); |
| } |
| |
| if (j == p.length()) return false; |
| |
| |
| if (p[j] != '*') return (s[i] == p[j] || p[j] == '?') && recursive(s, p, i + 1, j + 1); |
| |
| return recursive(s, p, i + 1, j) || recursive(s, p, i, j + 1); |
| } |
| |
| bool isMatch(string s, string p) { |
| return recursive(s, p, 0, 0); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| |
| class Solution { |
| public: |
| bool recursive(string s, string p, int i, int j, vector<vector<int>> &dp) { |
| if (dp[i][j] != 0) return dp[i][j] == 1; |
| bool res; |
| if (i == s.length()) { |
| if (j == p.length()) { |
| res = true; |
| } else { |
| res = p[j] == '*' && recursive(s, p, i, j + 1, dp); |
| } |
| } else if (j == p.length()) { |
| res = false; |
| } else { |
| if (p[j] != '*') { |
| res = (s[i] == p[j] || p[j] == '?') && recursive(s, p, i + 1, j + 1, dp); |
| } else { |
| res = recursive(s, p, i + 1, j, dp) || recursive(s, p, i, j + 1, dp); |
| } |
| } |
| dp[i][j] = res ? 1 : 2; |
| return res; |
| } |
| |
| bool isMatch(string s, string p) { |
| vector<vector<int>> dp(s.length() + 1, vector<int>(p.length() + 1)); |
| return recursive(s, p, 0, 0, dp); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| bool isMatch(string s, string p) { |
| int n = s.length(); |
| int m = p.length(); |
| vector<vector<bool>> dp(n + 1, vector<bool>(m + 1)); |
| dp[n][m] = true; |
| for (int j = m - 1; j >= 0 && p[j] == '*'; j--) |
| dp[n][j] = true; |
| for (int i = n - 1; i >= 0; i--) { |
| for (int j = m - 1; j >= 0; j--) { |
| if (p[j] != '*') { |
| dp[i][j] = (s[i] == p[j] || p[j] == '?') && dp[i + 1][j + 1]; |
| } else { |
| dp[i][j] = dp[i + 1][j] || dp[i][j + 1]; |
| } |
| } |
| } |
| return dp[0][0]; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| |
| |
| |
| |
| |
| int main() { |
| int n, h; |
| cin >> n >> h; |
| vector<int> cost(n + 1); |
| vector<int> value(n + 1); |
| int _max = 0; |
| for (int i = 1; i <= n; ++i) { |
| cin >> value[i] >> cost[i]; |
| _max = max(_max, value[i]); |
| } |
| |
| int m = h + _max; |
| |
| vector<vector<int>> dp(n + 1, vector<int>(m + 1)); |
| |
| fill(dp[0].begin() + 1, dp[0].end(), 0x7fffffff); |
| |
| dp[0][0] = 0; |
| for (int i = 1; i <= n; ++i) { |
| for (int j = 0; j <= m; ++j) { |
| dp[i][j] = dp[i - 1][j]; |
| if (j - value[i] >= 0 && dp[i][j - value[i]] != 0x7fffffff) |
| dp[i][j] = min(dp[i][j], dp[i][j - value[i]] + cost[i]); |
| } |
| } |
| int res = 0x7fffffff; |
| |
| for (int j = h; j <= m; ++j) |
| res = min(res, dp[n][j]); |
| cout << res << endl; |
| } |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| int main() { |
| int n, h; |
| cin >> n >> h; |
| vector<int> cost(n + 1); |
| vector<int> value(n + 1); |
| int _max = 0; |
| for (int i = 1; i <= n; ++i) { |
| cin >> value[i] >> cost[i]; |
| _max = max(_max, value[i]); |
| } |
| |
| int m = h + _max; |
| |
| vector<int> dp(m + 1, 0x7fffffff); |
| |
| dp[0] = 0; |
| for (int i = 1; i <= n; ++i) { |
| for (int j = value[i]; j <= m; ++j) { |
| if (dp[j - value[i]] != 0x7fffffff) |
| dp[j] = min(dp[j], dp[j - value[i]] + cost[i]); |
| } |
| } |
| int res = 0x7fffffff; |
| |
| for (int j = h; j <= m; ++j) |
| res = min(res, dp[j]); |
| cout << res << endl; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步