题目:某餐馆有n张桌子,每张桌子能容纳的最大人数为a;有m批客人,每批客人有两个参数:b人数,c预计消费金额数。在不允许拼桌的情况下,请选择其中一部分客人,使得总预计的消费金额最大。
输入:总共输入m+2行
第一行输入n m,即桌子的个数和客人的批数(1<=n<=50000;1<=m<=50000)
第二行是n个a,即每张桌子能容纳的客人数
接下来m行输入:b c,即每批客人的人数和预计消费金额
输出:一个整数,即总预计消费金额
测试实例:3 5
2 4 2
1 3
3 5
3 7
5 9
1 10
输出:20
思路:先用贪心算法对每批客人的消费金额进行降序排序,对金额相同的客人的人数进行升序排序;然后用二分法枚举每批客人去最合适的桌子。
代码(来自牛客网):
#include<iostrea>
#include<vector>
#include<map>
using namespace std;
struct node{//构造每批客人的人数和消费金额的结构体
int b,c;
};
std::multimap<int,int> mp;//用来存放餐厅一张桌子能容纳的客人数
std::vector<node> v;
int cmp(node x,node y){
if(x.c==y.c){
return x.b<y.b;
}
return x.c>y.c;
}
int n,m;//n-共有多少张桌子,m-共有多少批客人
long long ans;//消费的总金额
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){//获取每张桌子能容纳的客人数
int x;
scanf("%d",&x);
mp.insert(std::pair<int,int>(x,1));//pair赋值,若key(x)已经存在了,则不修改其值直接退出
}
for(int i=0;i<m;i++){//获取每批客人的情况并存入向量v
int x,y;
scanf("%d%d",&x,&y);
node temp;
temp.b=x;
temp.c=y;
v.push_back(temp);
}
sort(v.begin(),v.end(),cmp);//对消费金额降序排列,金额相同时对人数升序排列
for(int i=0;i<m;i++){
std::multimap<int,int>::iterator it=mp.lower_bound(v[i].b);//二分查找能够符合每桌容纳人数的客人
if(it!=mp.end()){
mp.erase(it);//删除这一张桌子
ans+=v[i].c;
}
}
printf("%11d\n",ans);
system("pause");
return 0;
}