题目描述
现有n组人,m个地点,给出每组人的人数,每个地点可容纳的最大人数和选择的价格
要求一种方式,使得每组人都到一个各不相同的地点,最小化选择的价格
每个队伍的人都要在同一个地方每个地方只能有一个队伍
输入描述:
第一行n,m 第二行n个数,表示每组的人数 接下来m行,每行两个数,表示可容纳的最大人数和选择的价格
输出描述:
输出最小化选择的价格,无解输出-1
示例1
输入
3 4 2 3 4 1 2 2 3 3 4 4 5
输出
12
备注:
所有数据小于1e5
题解:贪心,把人数场地人数与小组人数都从大到小排列,然后每次搜索匹配,把每次满足条件的情况中价格最小的,这里可以用优先队列,把满足条件的情况按价格从小到大排列,因为人数都是从大到小排列的,所以满足多人数的场地一定满足少人数的场地,不用将cnt复0,每次将所有情况加入后从中找到价格最小的一个场地即可,即是队列的队首
#include<bits/stdc++.h>
#include<queue>
using namespace std;
const int maxn = 1e5+10;
struct node{
int num;
int pri;
}t[maxn];
int cmpn(node a,node b)
{
return a.num > b.num;
}
int cmpp(int a,int b)
{
return a > b;
}
int main()
{
int n,m;
int peo[maxn];
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> peo[i];
}
for(int i = 0; i < m; i++){
cin >> t[i].num >> t[i].pri;
}
sort(t,t+m,cmpn);
sort(peo,peo+n,cmpp);
priority_queue< int , vector<int>, greater<int> >q; //从小到大排列
long long sum = 0;
int cnt = 0;
for(int i = 0; i < n; i++){
while(t[cnt].num >= peo[i]){ //场地人数满足小组成员,加入队列
q.push(t[cnt].pri);
cnt++; //cnt不用复位0,因为人数均从大到小排列,满足大的一定也满足小的
}
if (q.empty()){ //如果队列为空说明没有满足的场地,则输出-1
printf("-1\n");
return 0;
}
sum += q.top(); //选取最小的
q.pop();
}
cout << sum << endl;
return 0;
return 0;
}