题解 | 购物单

购物单

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

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

struct MainItem {
    int v, w;
    vector<pair<int, int>> attachments; // 存储附件的价格和重要度乘积
};

int main() {
    int n, m;
    cin >> n >> m;
    vector<tuple<int, int, int>> items; // 存储所有物品的信息:v, w, q
    for (int i = 0; i < m; ++i) {
        int v, w, q;
        cin >> v >> w >> q;
        items.emplace_back(v, w, q);
    }

    map<int, MainItem> mainItems;

    // 处理主件
    for (int i = 0; i < m; ++i) {
        int v = get<0>(items[i]);
        int w = get<1>(items[i]);
        int q = get<2>(items[i]);
        if (q == 0) { // 主件
            int id = i + 1; // 物品编号从1开始
            mainItems[id] = {v, w, {}};
        }
    }

    // 处理附件
    for (int i = 0; i < m; ++i) {
        int v = get<0>(items[i]);
        int w = get<1>(items[i]);
        int q = get<2>(items[i]);
        if (q != 0) { // 附件
            int main_id = q;
            if (mainItems.find(main_id) != mainItems.end()) {
                mainItems[main_id].attachments.emplace_back(v, w);
            }
        }
    }

    // 生成所有主件的组合
    vector<vector<pair<int, int>>> groups;
    for (auto &entry : mainItems) {
        MainItem &main = entry.second;
        int k = main.attachments.size();
        vector<pair<int, int>> combs;
        for (int mask = 0; mask < (1 << k); ++mask) {
            int price = main.v;
            int satis = main.v * main.w;
            for (int i = 0; i < k; ++i) {
                if (mask & (1 << i)) {
                    price += main.attachments[i].first;
                    satis += main.attachments[i].first * main.attachments[i].second;
                }
            }
            combs.emplace_back(price, satis);
        }
        groups.push_back(combs);
    }

    // 动态规划处理分组背包
    vector<int> dp(n + 1, 0);
    for (auto &group : groups) {
        for (int j = n; j >= 0; --j) {
            int current_max = dp[j];
            for (auto &comb : group) {
                int price = comb.first;
                int satis = comb.second;
                if (j >= price) {
                    current_max = max(current_max, dp[j - price] + satis);
                }
            }
            dp[j] = current_max;
        }
    }

    cout << dp[n] << endl;
    return 0;
}

#选择和努力,哪个更重要?##我是XXX,请攻击我最薄弱的地方#
全部评论

相关推荐

已oc&nbsp;云智断更了好几天,也有一些话想说,继续更新一篇云智timeline&nbsp;4.18&nbsp;一面&nbsp;半个小时后约二面&nbsp;4.21二面&nbsp;当晚&nbsp;约hr面&nbsp;4.23hr面&nbsp;4.30&nbsp;发offer之前美团的二面挂了,进入人才库,后面又被捞起来面试,4.30号&nbsp;美团又一面,现在还没出一面结果感觉也不报什么希望,就算一面过了,还有二面,我经不起深入拷打,唉,真的,好难五一躺平了五天,吃吃玩玩睡睡~还要担心毕业,科研更是难,唉暑期可能就到此为止了,后面没有时间在这个上面了,要抓紧时间做科研,为了后面能出去实习。大厂,秋招再见!!!有一些感慨:4.1是我的第一次面试,美团,面试的时候紧张到浑身发...
daisy9542:我今晚也是美团一面,已经第六次了。我也面了其他的,没拿到 offer。但我想开了,要按照自己的节奏来,找暑期转正然后秋招大杀四方并不是唯一的出路,其实还有很多选择的,有 0 实习最后秋招拿 offer 了,也有不选择互联网去国企的外企的,考编的,创业的。现在的失败不代表以后的路都是黑暗的,只不过可能运气还没降临到头上。所以现在要做的,就是放平心态,提升自己,通过面试了解到自己的优点和不足,争取下次机会来了能好好抓住
点赞 评论 收藏
分享
点赞 评论 收藏
分享
吴offer选手:学到了,下次面试也放张纸在电脑上,不然老是忘记要说哪几个点
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务