算法思想
略,可用priority_queue实现
训练
HDU4006
题目大意:n轮,每次可以记录一个数或询问第k大的数是什么,分别对应I c和Q,求每次询问的结果
思路:用优先队列记录当前的前k大的数字即可,用小顶堆
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;
int n,k,x;
char ch;
int main() {
while(~scanf("%d%d",&n,&k)) {
priority_queue<int,vector<int>,greater<int>>Q;
while(n--) {
cin >>ch;
if(ch=='I') {
scanf("%d",&x);
if(Q.size()<k)//如果能存
Q.push(x);
else if(Q.top()<x) {//如果比堆顶小,代表堆顶不为当前第k大的数
Q.pop();
Q.push(x);
}
} else
printf("%d\n",Q.top());
}
}
return 0;
}
POJ3253
题目大意:N块木板,每块长度为 L i L_i Li,一开始是一整个木板,现在要切成N块,每次费用为切出的木板长度和,求最小费用
思路:用哈夫曼树的思想,使用优先队列模拟完成,注意long long
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long ll;
ll N,L,ans;
priority_queue<ll,vector<ll>,greater<ll>>Q;
int main() {
scanf("%d",&N);
for(int i=0; i<N; i++) {
scanf("%lld",&L);
Q.push(L);
}
while(Q.size()!=1) {
ll t=0;
t+=Q.top();
Q.pop();
t+=Q.top();
Q.pop();
Q.push(t);
ans+=t;
}
if(ans==0)
ans+=Q.top();
printf("%lld",ans);
return 0;
}
POJ2833
题目大意:给n个正整数,去掉 n 1 n_1 n1个最大值,去掉 n 2 n_2 n2个最小值,求剩下的平均值
思路:维护一个优先队列来存前 n 1 n_1 n1个最大值和 n 2 n_2 n2个最小值
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
ll n1,n2,n,x;
int main() {
while(~scanf("%lld%lld%lld",&n1,&n2,&n)&&n1&&n2&&n) {
priority_queue<ll,vector<ll>,less<ll>>Q2;
priority_queue<ll,vector<ll>,greater<ll>>Q1;
ll ans=0;
for(int i=0; i<n; i++) {
scanf("%lld",&x);
if(Q1.size()<n1)
Q1.push(x);
else if(Q1.top()<x)
Q1.pop(),Q1.push(x);
if(Q2.size()<n2)
Q2.push(x);
else if (Q2.top()>x)
Q2.pop(),Q2.push(x);
ans+=x;
}
while(!Q1.empty()) {
ans-=Q1.top();
Q1.pop();
}
while(!Q2.empty()) {
ans-=Q2.top();
Q2.pop();
}
printf("%.6f\n",(double)ans/(n-n1-n2));
}
return 0;
}
POJ2431
题目大意:一辆车,走一里一升油,一开始有P升,距目的地L,路上有N个加油站,各自能提供 f i f_i fi升,问到达目的地最少加油次数,不能到达输出-1
思路:贪心+优先队列
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int N,ans,L,P;
typedef struct node {
int L,P;
bool operator<(node a)const {
return L>a.L;
}
} node;
node power[12121];
int main() {
scanf("%d",&N);
for(int i=0; i<N; i++)
scanf("%d%d",&power[i].L,&power[i].P);
scanf("%d%d",&L,&P);
sort(power,power+N);//排序
priority_queue<int>Q;
int pos=P,k=0;//pos为当前可到达最远距离
while(pos<L) {
while(pos>=L-power[k].L&&k<N)//如果油够用
Q.push(power[k++].P);
if(Q.empty()) {
printf("-1");
return 0;
}
pos+=Q.top();//油不够,加油
Q.pop();
ans++;
}
printf("%d",ans);
return 0;
}
总结
优先队列的用法较简单,一般用其性质进行最值的求解