题目描述
现有n组人,m个地点,给出每组人的人数,每个地点可容纳的最大人数和选择的价格
要求一种方式,使得每组人都到一个各不相同的地点,最小化选择的价格
每个队伍的人都要在同一个地方每个地方只能有一个队伍
输入描述:
第一行n,m 第二行n个数,表示每组的人数 接下来m行,每行两个数,表示可容纳的最大人数和选择的价格
输出描述:
输出最小化选择的价格,无解输出-1
示例1
输入
3 4 2 3 4 1 2 2 3 3 4 4 5
输出
12
备注:
所有的数据都小于1e5
题解:我们可以先将n组人排好序,和m个地点排好序
那么对于n组人中最大的来说,将m个地点中大于其的全部加入优先队列。优先队列里存的是可以放下当前组的花费。
只需要从中选出一个最小的花费即可,对于下一个组来说,能放下上一个组的地点也能放下该组,于是继续向优先队列中放入满足的花费。
只需要保证优先队列中都是满足条件的地点即可。
当优先队列为空时就是无解的时候。
代码:
/**
优先队列默认数值大的优先级高!!
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
typedef long long ll;
struct Place {
ll cal,val;
friend bool operator<(Place node1,Place node2)
{
return node1.val > node2.val;
}
};
Place num[maxn];
ll arr[maxn];
bool vis[maxn];
bool cmp(const Place &a,const Place &b) {
if(a.cal == b.cal) return a.val < b.val;
return a.cal < b.cal;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
priority_queue<ll,vector<ll>,greater<ll> > qu;
//memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++) scanf("%lld",&arr[i]);
for(int i=0;i<m;i++) {
scanf("%lld%lld",&num[i].cal,&num[i].val);
}
bool flag = true;
ll ans = 0;
sort(arr,arr+n);
sort(num,num+m,cmp);
for(int i=n-1,j=m-1;i>=0;i--) {
while(j>=0 && num[j].cal >= arr[i]) qu.push(num[j].val),j--;
if(qu.empty()) {
flag = false;
break;
}
else {
ll temp = qu.top();
qu.pop();
ans += temp;
}
}
if(flag == false) printf("-1\n");
else printf("%lld\n",ans);
}
return 0;
}