原题链接:金明的预算方案
解题思路:DP (分别考虑只拿主件, 主件+ 1附件, 主件 + 2附件)
注意事项:
参考代码:
#include<bits/stdc++.h>
using namespace std;
// 定义常量 N,用于确定数组的最大长度
const int N = 2e5 + 10;
// 全局变量声明
int n, m, dp[N]; // n 表示背包的最大容量,m 表示物品的数量,dp 数组用于动态规划
// 定义结构体 node,用于存储物品信息
struct node{
int w, p; // w 表示物品的重要程度,p 表示物品的价值
};
// 定义一个数组,数组的每个元素是一个存储 node 结构体的向量
// 用于将物品按组存储,a[i] 表示第 i 组的物品
vector<node> a[N];
int main()
{
// 从标准输入读取背包的最大容量 n 和物品的数量 m
cin >> n >> m;
// 循环读取每个物品的信息
for(int i = 1; i <= m; ++ i){
int w, p, idx;
// 读取物品的价值 p、重要程度 w 和所属组的索引 idx
cin >> p >> w >> idx;
if (!idx) a[i].push_back({w,p}); // 若 idx 为 0,将该物品放入第 i 组
else a[idx].push_back({w,p}); // 否则,将该物品放入第 idx 组
}
// 动态规划过程,遍历每一组物品
for(int i = 1; i <= m; ++ i){
// 若第 i 组有物品
if(a[i].size() > 0)
// 从背包最大容量 n 开始,逆向遍历到该组第一个物品的重量
for(int j = n; j >= a[i][0].p; j --){
int t = j, ac = 0; // t 记录当前剩余容量,ac 记录当前累计价值
// 遍历第 i 组的所有物品
for(int k = 0; k < a[i].size(); ++ k){
// 若当前剩余容量足够放入第 k 个物品
if(t >= a[i][k].p){
t -= a[i][k].p; // 减去该物品的价值,更新剩余金钱
ac += a[i][k].w * a[i][k].p; // 累加该物品的价值,更新累计价值
}
// 更新 dp[j] 为当前值和新方案值中的较大值
dp[j] = max(dp[j], dp[t] + ac);
}
}
}
// 输出背包容量为 n 时能获得的最大价值
cout << dp[n];
return 0;
}0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复