题目:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2223
题意:N个人排队在M个出水口前接水,第i个人接水需时为t[i],请问接水的最短用时是多少?
分析:贪心+二叉堆。将所有人从大到小排序,依次插入M个出水口,
每次要插入到用时最小的出水口,最后输出M个出水口中用时最多的那一个。
本代码用优先队列实现
#include<stdio.h>
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
/*本题思路:贪心+二叉堆。将所有人从大到小排序,依次插入M个出水口,
每次要插入到用时最小的出水口,最后输出M个出水口中用时最多的那一个。
本代码用优先队列实现*/
int cmp(int a,int b){//用于sort从大到小排序
return a>b;
}
int tim[101000];
int main(){
int T,N,M;
cin >> T;
while(T--){
cin >>N >> M;
priority_queue<int,vector<int>,greater<int> > pq;//优先队列,从小到大入队列
for(int i=0;i<M;i++) //将M个出水口用时初始化为0
pq.push(0);
for(int i=0;i<N;i++)
cin >> tim[i];
sort(tim,tim+N,cmp); //从大到小排序
for(int i=0;i<N;i++){
int temp= pq.top(); //每次取出时间最小的出水口
pq.pop(); //出队列
temp+=tim[i]; //将第i个人插入到 目前时间最小的出水口
pq.push(temp); //将这个出水口入队列。然后优先队列会自动排序。
}
int ans=-1;
while(!pq.empty()){ //遍历循环,找出最大值
if(ans<pq.top()) ans=pq.top();
pq.pop();
}
printf("%d\n",ans);
}
return 0;
}