笔试专题,牛客网,餐馆

链接: https://www.nowcoder.com/questionTerminal/d2cced737eb54a3aa550f53bb3cc19d0
来源:牛客网

某餐馆有n张桌子,每张桌子有一个参数:a 可容纳的最大人数; 有m批客人,每批客人有两个参数:b人数,c预计消费金额。 在不允许拼桌的情况下,请实现一个算法选择其中一部分客人,使得总预计消费金额最大
输入描述:
输入包括m+2行。 第一行两个整数n(1 <= n <= 50000),m(1 <= m <= 50000) 第二行为n个参数a,即每个桌子可容纳的最大人数,以空格分隔,范围均在32位int范围内。 接下来m行,每行两个参数b,c。分别表示第i批客人的人数和预计消费金额,以空格分隔,范围均在32位int范围内。


输出描述:
输出一个整数,表示最大的总预计消费金额
示例1

输入

3 5 2 4 2 1 3 3 5 3 7 5 9 1 10

输出

20

题意简单理解,这些顾客分为几批,但都是一起来的,他们每一批都不想分开坐,所以要把这几批人都分别安排在一个桌子上,但是为了谋求最大的经济效益,来的人有多有少,分给他们的桌子就要从人数来判断。比如有一批人来,把他们呢从带来的钱来排序比较,钱最多要优先分配,因为桌子就那几张桌子,每个桌子带来的收益最高,那么整体的收益就是最大的,前提条件是不能拼桌,所以当我们看到带最多的钱的人来时,我么就从桌子容量数目最少的(桌子是升序的)开始寻找能够容纳人数的桌子,如果这队人数少于最大容纳量,那么就把这些钱记录下来,收录这些人,接下来再寻找下一队带钱最多的人。


方法1.

链接:https://www.nowcoder.com/questionTerminal/d2cced737eb54a3aa550f53bb3cc19d0
来源:牛客网


/*
思路:优先选消费额度大的客人安排就餐
对客人按照消费额度排序(大->小)
对桌子按照容量排序(大->小)
选取当前消费额度最大客人:
1.如果没有桌子可用,结束;
2.如果人数过多无法安排,跳过;
3.如果可安排,则找到最合适的桌位,可就餐的桌位中容量最小的;
   3.1向这批客人收费;
   3.2将桌子从可用资源中删除;
直到没有桌子可用或所有客人全部安排
*/
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
    int n, m, b, c;
    int num;
    vector< int > desk; //可用桌子资源的容量
    vector<pair< int , int >> customer; //预计消费,人数
    cin >> n >> m;
    while (n--) //输入桌子容量
    {
        cin >> num;
        desk.push_back(num);
    }
    //对桌子容量从大到小排序
    sort(desk.begin(), desk.end());
    reverse(desk.begin(), desk.end());
    vector< bool > flag(desk.size(), false );
    while (m--)
    {
        cin >> b >> c;
        customer.push_back(make_pair(c, b));
    }
    //对顾客按消费额度从大到小排序
    sort(customer.begin(), customer.end());
    reverse(customer.begin(), customer.end());
     
    long long ret = 0; //必须是long long,int会溢出
    for ( int it = 0; it < customer.size(); ++it)
    {
        if (desk.size() == 0) //没有可用的桌子了
            break ;
        int consumeMoney = customer[it].first;
        int countOfPeople = customer[it].second;
        if (desk[0] < countOfPeople) //最大的桌子也容不下这批客人
            continue ;
        int i = 0;
        while (i < desk.size() && desk[i] >= countOfPeople) //找到可以容纳这批客人的最小桌子
            ++i; //i为第一个不可容纳的桌子,则i-1位这批客人的最佳桌位
        ret = ret + consumeMoney; //收入增加
        desk.erase(desk.begin() + i - 1); //桌子从可用资源中删除
    }
    cout << ret << endl;
}

方法2

链接:https://www.nowcoder.com/questionTerminal/d2cced737eb54a3aa550f53bb3cc19d0

来源:牛客网

这个使用multiset特点来进行使用的,用low_bound直接来寻找第一个大于等于val值的下标


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
 
struct guest {
     int num;
     int money;
};
bool cmp(guest a, guest b) {
     if (a.money == b.money) {
         return a.num < b.num;
     }
     return a.money > b.money;
}
int main() {
     using namespace std;
     int n, m;
     while (cin >> n >> m) {
         multiset< int > desk;
         vector<guest> people(m);
         long long ans = 0 ;
         for ( int i = 0 ; i < n; i++) {
             int temp;
             cin >> temp;
             desk.insert(temp);
         }
         for ( int i = 0 ; i < m; i++) {
             int a, b;
             cin >> a >> b;
             people[i].num = a;
             people[i].money = b;
         }
         sort(people.begin(), people.end(), cmp);
         for ( int i = 0 ; i < m; i++) {
             if (desk.empty()) {
                 break ;
             }
             if (people[i].num <= *desk.rbegin()) {
                 ans += people[i].money;
                 desk.erase(desk.lower_bound(people[i].num));
             }
         }
         cout << ans << endl;
     }
     return 0 ;
}

方法3

另一种方法是利用了优先序列的方法,自动对数据集从大到小排序,在查找方面可以使用二分法

链接:https://www.nowcoder.com/questionTerminal/d2cced737eb54a3aa550f53bb3cc19d0
来源:牛客网

include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
 
struct custom {
     int num;
     int cost;
};
class queue_cmp {
public :
     bool operator()(custom a, custom b) {
         return a.cost < b.cost;
     }
};
bool sort_cmp(custom a, custom b) {
     return a.num < b.num;
}
int main() {
     int n, m;
     cin >> n >> m;
     vector< int > tables(n);
     vector<custom> customs(m);
     for ( int i = 0; i < n; i++)
         cin >> tables[i];
     for ( int i = 0; i < m; i++)
         cin >> customs[i].num >> customs[i].cost;
     sort(tables.begin(), tables.end());
     sort(customs.begin(), customs.end(),sort_cmp);
     priority_queue<custom, vector<custom>, queue_cmp> que;
     long long sum = 0;
     int j = 0;
     for ( int i = 0; i < n; i++) {
         for (; j < m && customs[j].num <= tables[i]; j++)
             que.push(customs[j]);
         if (que.empty()) continue ;
         sum += que.top().cost;
         que.pop();
     }
     cout << sum << endl;
     return 0;
}

fa

猜你喜欢

转载自blog.csdn.net/qq_40086556/article/details/80039206
今日推荐