01背包,完全背包,分组背包,多重背包例题
一.01背包
416. 分割等和子集 - 力扣(LeetCode)
class Solution {
public:bool canPartition(vector<int>& nums) {int sum=0;for(int i=0;i<nums.size();i++){sum+=nums[i];}int k=0;if(sum%2!=0){return false;}k=sum/2;vector<int>dp(k+1,0);for(int i=0;i<nums.size();i++){for(int j=k;j>=0;j--){if(j>=nums[i]){dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);}}}if(dp[k]==k){return true;}return false;}
};
二.完全背包:
P1616 疯狂的采药 - 洛谷
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<map>
#include<set>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<cmath>
#include<iomanip>
#include<limits>
using namespace std;
#define int long long
void solve() {int n, m;cin >> n >> m;vector<int>times(m + 1), val(m + 1);for (int i = 0; i < m; i++) {cin >> times[i] >> val[i];}vector<int>dp(n + 1, 0);for (int i = 0; i < m; i++) {for (int j = 0; j <= n; j++) {if(j>=times[i])dp[j] = max(dp[j], dp[j - times[i]] + val[i]);}}cout << dp[n] << endl;}
signed main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;t = 1;while (t--)solve();return 0;
}
三.分组背包:
P1757 通天之分组背包 - 洛谷
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void solve() {vector<vector<int>>w(102, vector<int>(1002, 0));vector<vector<int>>v(102, vector<int>(1002, 0));int n, m;cin >> m>>n;int maxn = 0;for (int i = 0; i < n; i++) {int a, b, c;cin >> a >> b >> c;w[c].push_back(a);v[c].push_back(b);maxn = max(maxn, c);}vector<vector<int>>dp(maxn+1,vector<int>(m+1,0));for (int i = 1; i <= maxn; i++) {for (int j = 0; j<=m; j++) {for (int k = 0; k < w[i].size(); k++) {if (j >= w[i][k]) {dp[i][j] = max(dp[i][j], dp[i - 1][j - w[i][k]] + v[i][k]);}}}}cout << dp[maxn][m] << endl;
}
signed main() {int t = 1;while (t--)solve();return 0;
}
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void solve() {vector<vector<int>>w(102, vector<int>(1002, 0));vector<vector<int>>v(102, vector<int>(1002, 0));int n, m;cin >> m >> n;int maxn = 0;for (int i = 0; i < n; i++) {int a, b, c;cin >> a >> b >> c;w[c].push_back(a);v[c].push_back(b);maxn = max(maxn, c);}vector<int>dp(m + 1, 0);for (int i = 1; i <= maxn; i++) {for (int j = m; j >= 0; j--) {for (int k = 0; k < w[i].size(); k++) {if (j >= w[i][k]) {dp[j] = max(dp[j], dp[j - w[i][k]] + v[i][k]);}}}}cout << dp[m] << endl;
}
signed main() {int t = 1;while (t--)solve();return 0;
}
四.多重背包:
4. 多重背包问题 I - AcWing题库
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void solve() {int n, m;cin >> n >> m;vector<int>v(n), w(n), s(n);for (int i = 0; i < n; i++) {cin >> v[i] >> w[i] >> s[i];}vector<int>dp(m + 1, 0);for (int i = 0; i < n; i++) {for (int j = m; j >= 0; j--) {for (int k = 1; k <= s[i]&&k*v[i]<=j; k++) {dp[j] = max(dp[j], dp[j - k * v[i]] + k * w[i]);}}}cout << dp[m] << endl;
}
signed main() {int t = 1;while (t--)solve();return 0;
}