解题思路: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分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论