当前位置:首页 > 牛客 > 牛客12650题解析:基于贪心算法的桌子与客人匹配问题

牛客12650题解析:基于贪心算法的桌子与客人匹配问题

4个月前 (08-02)

牛客12650题解析:基于贪心算法的桌子与客人匹配问题 牛客题解 贪心算法 C++ 第1张

一、题目解读

牛客12650题要求处理一个资源分配问题:给定n张不同容量的桌子与m个携带消费金额的客人,客人需匹配到可容纳人数的桌子,目标是最大化所有匹配客人的总消费金额。题目本质是约束条件下的优化问题,需平衡桌子容量与客人需求的匹配效率。

二、解题思路

1. 贪心策略核心:优先安排高消费金额的客人,确保“价值最大化”的匹配。

2. 数据结构选择:

    桌子容量存入multiset(支持自动排序与快速查找),便于动态删除已占用桌子。

    客人信息用vector存储,按消费金额降序排序,确保优先处理高价值客人。

3. 关键操作:通过lower_bound定位首个满足容量要求的桌子,实现O(logn)查找效率,避免暴力遍历。

三、解题步骤

1. 输入处理:

    读取桌子容量并存入multiset,自动升序排列。

    读取客人信息(人数与消费金额),存入vector后排序(金额降序)。

2. 匹配逻辑:

    遍历客人列表,对每个客人调用tables.lower_bound(人数)查找合适桌子。

    若找到桌子,累加消费金额并删除该桌子(避免重复使用)。

3. 输出结果:最终累计的消费总额即为最优解。

四、代码与注释

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

// 客人结构体(按消费金额降序排序)
struct Guest {
    int b; // 人数
    int c; // 消费金额
    bool operator<(const Guest& other) const {
        return c > other.c; // 自定义排序规则:金额降序
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); // 加速输入

    int n, m; // 桌子数量、客人数量
    cin >> n >> m;

    // 桌子容量存入multiset(自动排序)
    multiset<int> tables;
    for (int i = 0; i < n; ++i) {
        int a;
        cin >> a;
        tables.insert(a);
    }

    // 客人信息读取与排序
    vector<Guest> guests(m);
    for (int i = 0; i < m; ++i) {
        cin >> guests[i].b >> guests[i].c;
    }
    sort(guests.begin(), guests.end()); // 按消费金额降序排列

    long long total = 0; // 累计消费金额
    for (const auto& guest : guests) {
        // 查找首个满足人数的桌子(O(logn))
        auto it = tables.lower_bound(guest.b);
        if (it!= tables.end()) {
            total += guest.c;
            tables.erase(it); // 删除已占用桌子
        }
    }

    cout << total << endl;
    return 0;
}

五、总结

本解法通过“贪心+数据结构优化”实现高效解题:

● 排序与lower_bound的结合避免了复杂匹配搜索,时间复杂度O(mlogn)。

● 动态删除占用桌子确保解的唯一性,符合题目约束。

● 代码结构清晰,注释明确,适用于算法面试与工程实践。



原创内容 转载请注明出处

分享给朋友:

相关文章

力扣145:递归之美 轻松掌握二叉树后序遍历

力扣145:递归之美 轻松掌握二叉树后序遍历

题目解读二叉树的后序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。这种遍历方式特别适合需要先处理子节点再处理父节点的场景,如内存释放...

力扣144:递归之美 轻松掌握二叉树前序遍历

力扣144:递归之美 轻松掌握二叉树前序遍历

题目解读二叉树的前序遍历是一种基础但重要的树遍历方式,其遍历顺序为:先访问根节点,然后递归地前序遍历左子树,最后递归地前序遍历右子树。给定一个二叉树的根节点,我们需要按照这个顺序访问所有节点,并将它们...

力扣965题深度解析:单值二叉树的判断技巧

力扣965题深度解析:单值二叉树的判断技巧

重新解读题目 判断一棵二叉树是否为“单值二叉树”,即所有节点的值是否完全相同。题目看似简单,实则考验对树结构递归特性的理解。若一棵树的所有节点值相同,其必然满足:根节点与左右子树的值一致,且...

洛谷P1007士兵过桥问题详解 C++贪心算法实现与优化

洛谷P1007士兵过桥问题详解 C++贪心算法实现与优化

题目解读这道题目描述了一座长度为L的桥上有n个士兵,每个士兵每秒可以向左或向右移动1个单位。当士兵到达桥的端点(0或L+1)时离开桥。要求计算所有士兵离开桥的最小时和最大时间。解题思路最小时计算:每个...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

一、题目解读洛谷1184题要求处理一组地点列表与行程记录,统计其中匹配的天数。题目难点在于高效处理带有空格的字符串输入,以及快速判断每日行程是否在高手可去地点集合中。需要兼顾输入格式解析与算法效率。二...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。