链接:
https://www.nowcoder.com/acm/contest/112/A
来源:牛客网
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
现有n组人,m个地点,给出每组人的人数,每个地点可容纳的最大人数和选择的价格
要求一种方式,使得每组人都到一个各不相同的地点,最小化选择的价格
每个队伍的人都要在同一个地方每个地方只能有一个队伍
输入描述:
第一行n,m 第二行n个数,表示每组的人数 接下来m行,每行两个数,表示可容纳的最大人数和选择的价格
输出描述:
输出最小化选择的价格,无解输出-1
思路:贪心的思想
把每个地点的价钱从小到大排序,尽量让较多的人去到钱较少的组里
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<set>
using namespace std;
typedef pair<int,int> P;
multiset<int>team;
priority_queue<P,vector<P>,greater<P> >place;//地点按照价钱从小到大排
int main(){
int n,m,num,a,b;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&num);
team.insert(num);
}
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
place.push(P(b,a));//以价格排序
}
int sum=0;
while(place.size()){
P p=place.top();
set<int>::iterator it=team.upper_bound(p.second);//返回第一个大于p.second的元素
if(it!=team.begin()){/*若it=team.begin()说明第一个元素大于,则没有元素小于或等于,不符合。若没有一个元素大于,说明都符合,则it=team.end(),it--;指向集合中最大的元素*/
sum+=p.first;
team.erase(--it);
}
place.pop();
if(!team.size())break;
}
if(team.size()){
printf("-1\n");
}
else printf("%d\n",sum);
}