题解 | #购物单#

购物单

https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

#include <iostream>
#include <unordered_map>
#include <vector>
#include <map>
using namespace std;

int main() {
    int money, num;
    while (cin >> money >> num) { // 注意 while 处理多个 case
        vector<int> price(61, 0);
        vector<int> importance(61, 0);
        vector<int> parent(61, 0);
        vector<int> db(3201, 0);
        unordered_map<int, vector<int>> father;
        for (int i = 1; i < num + 1; i++) {
            int price_orign;
            cin >> price_orign >> importance[i] >> parent[i];
            price[i] = price_orign /
                       10; //价格和物品单价整除10,减少遍历次数
            if (parent[i] == 0) {
                father.insert(pair<int, vector<int>>(i, vector<int>(1,
                                                     0))); //主键map初始化
            }
        }
        //单独遍历一次防止附件再主键值前插入导致【i】【0】为非预期值
        for (int i = 1; i < num; i++) {
            if (parent[i] != 0) {
                father[parent[i]].push_back(i);
                father[parent[i]][0]++;//将主键附件关系记录
            }
        }
        for (int i = 1; i < num + 1 ; i++) {
            for (int j = money / 10; j > 0; j--) {
                if (parent[i] == 0) {
                    //买本体
                    //买本体加附件一
                    //买本体加附件二
                    //买本体加附件一二
                    if (j >= price[i]) {

                        db[j] = max(db[j], db[j - price[i]] + price[i] * importance[i]);
                    }
                    //考虑附件
                    if (father[i][0] == 1) {
                        int cur_annex = father[i][1];
                        if (j >= price[i] + price[cur_annex]) {
                            db[j] = max(db[j], db[j - price[i] - price[cur_annex]] + price[i] *
                                        importance[i] + price[cur_annex] *
                                        importance[cur_annex]); //主键已在上一步进行了比对,所以此时的db【j】已经取了较大值
                        }

                    }
                    if (father[i][0] == 2) {
                        int first_annex = father[i][1];
                        int second_annex = father[i][2];
                        if (j >= price[i] + price[first_annex]) {
                            db[j] = max(db[j], db[j - price[i] - price[first_annex]] + price[i] *
                                        importance[i] + price[first_annex] *
                                        importance[first_annex]); //考虑附件1
                        }
                        if (j >= price[i] + price[second_annex]) {
                            db[j] = max(db[j], db[j - price[i] - price[second_annex]] + price[i] *
                                        importance[i] + price[second_annex] *
                                        importance[second_annex]); //考虑附件2
                        }
                        if (j >= price[i] + price[first_annex] + price[second_annex]) {
                            db[j] = max(db[j], db[j - price[i] - price[first_annex] - price[second_annex]] +
                                        price[i] * importance[i] + price[first_annex] * importance[first_annex] +
                                        price[second_annex] * importance[second_annex]);//考虑附件12
                        }
                    }

                }
            }
        }
        cout << db[money / 10] * 10;

    }
}
// 64 位输出请用 printf("%lld")

背包问题卡了很久,最后选择用自己比较好理解的逻辑来做,主要根据题目进行问题拆解,根据题目中提供的物品上限以及附件主键依赖关系实现

全部评论

相关推荐

06-12 16:00
天津大学 Java
牛客30236098...:腾讯坏事做尽,终面挂是最破防的 上次被挂了后我连简历都不刷了
点赞 评论 收藏
分享
06-13 10:15
门头沟学院 Java
想去夏威夷的大西瓜在...:我也是27届,但是我现在研一下了啥项目都没有呀咋办,哎,简历不知道咋写
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务