滴滴2017笔试

某餐馆有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

输出例子1:

20

题目应该从最大金额开始选,但是要满足人数够就行了,c++的stl中有个lower_bound函数正好就是查询大于等于某个给定值的迭代器的,(顺便说一句,upper_bound函数是选择大于的,而不是大于等于的

这也是参考别的博客里的写法。因为每桌的人数和金额是一体的,很自然想到要写结构体。

先按金额降序排,金额相同时要按照人数升序排(因为我们更想要人数少,金额大的情况)

因为lower_bound只对map有效,vector并不能用,所以这里强行构造了一个map,该map的键是第二行数字,值给固定值,无意义。

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
struct my_node
{
int b; int c;
my_node(int x_b, int x_c) :b(x_b), c(x_c){};
};
bool cmp(my_node node1, my_node node2)
{
if (node1.c!=node2.c)
{
return node1.c > node2.c;
}
else
{
return node1.b < node2.b;
}
}
int main()
{
int n, m;
multimap<int, int>table_renshu;
while (cin>>n>>m)
{
for (int i = 0; i < n;i++)
{
int temp; cin >> temp;
table_renshu.insert(make_pair(temp, 1));
}
vector<my_node>m_data;
for (int i = 0; i < m;i++)
{
int b; int c;
cin >> b >> c;
my_node temp(b,c);
m_data.push_back(temp);
}


sort(m_data.begin(),m_data.end(), cmp);
//int ans=0;
long long ans = 0;
for (int i = 0; i < m;i++)
{
multimap<int, int>::iterator it = table_renshu.lower_bound(m_data[i].b);
if (it != table_renshu.end())
{
ans += m_data[i].c;
table_renshu.erase(it);
}
}
cout << ans << endl;
}
return 0;


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值