1 条题解
-
0
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int N, M; // N: 总预算,M: 主商品数量 cin >> N >> M; // 存储每组商品(主件及其附件)的所有可能组合(花费,满意度) vector<vector<pair<int, int>>> groups; // 处理每个主商品 for (int i = 0; i < M; i++) { int v, p, q; // v: 主件价格,p: 主件满意度,q: 附属商品数量 cin >> v >> p >> q; vector<pair<int, int>> accessories; // 存储附属商品的价格和满意度 for (int j = 0; j < q; j++) { int a, b; // a: 附属商品价格,b: 附属商品满意度 cin >> a >> b; accessories.push_back({a, b}); } // 生成当前主件的所有可能组合(包括不买附件、买一个附件、买两个附件等) vector<pair<int, int>> choices; int states = 1 << q; // 使用位运算表示所有可能的组合,每个位表示是否购买对应的附件 for (int s = 0; s < states; s++) { int total_cost = v; // 总花费至少包括主件价格 int total_value = p; // 总满意度至少包括主件满意度 // 遍历每个附件,根据位运算状态决定是否购买 for (int k = 0; k < q; k++) { if (s & (1 << k)) { // 如果第k个附件被选中 total_cost += accessories[k].first; total_value += accessories[k].second; } } // 如果当前组合的花费不超过总预算,则将其加入可选组合 if (total_cost <= N) { choices.push_back({total_cost, total_value}); } } // 将当前主件的所有组合加入组列表 groups.push_back(choices); } // 动态规划数组,dp[j]表示花费j元能获得的最大满意度 vector<int> dp(N + 1, 0); // 遍历每组商品 for (size_t i = 0; i < groups.size(); i++) { // 从大到小遍历预算,避免重复选择同一组内的多个组合 for (int j = N; j >= 0; j--) { // 遍历当前组内的每个组合 for (auto& choice : groups[i]) { int cost = choice.first; int value = choice.second; // 如果当前预算j足够支付该组合的花费 if (j >= cost) { // 更新dp[j]: 比较当前值和选择该组合后的值 dp[j] = max(dp[j], dp[j - cost] + value); } } } } // 输出在总预算N下能获得的最大满意度 cout << dp[N] << endl; return 0; }
- 1
信息
- ID
- 155
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者