题目描述
现有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; }