标签:
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 7696 | Accepted: 2260 |
Description
Input
Output
Sample Input
4 4 4 5 2 11 5 15 10 25 10
Sample Output
2
Hint
Source
题意:以汽车要行驶距离L的路程,路上有n个加油站,车从起点出发,在起点时,车上有汽油容量为p,已知单位距离1,就会消耗汽油1,已知n个加油站距离终点的距离和各个加油站可以加的油量,然后问最少需要加多少次油可以到达终点,若不能到达终点,输出“-1”。
解析:按照贪心的思想,我们肯定是尽可能的把油用完了再加,但是每个加油站的加油量有区别,这样就不能简单的贪心了。我们可以这样看,由于不知道什么时候加最合适,所以我们可以先把那些途经的加油站的油量全部放到优先级队列里,到后来需要的时候再加上,就相当于是经过那个站的时候把油给加上了,效果是一样的。这样就可以了,每次加的都是油量最大的,所以最后的加油次数就是最少的。
AC代码:
#include <cstdio>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 10002
int a[maxn], b[maxn];
struct node{ int a; int b; }; //加油站结构体,位置a,油量b
node m[maxn];
bool cmp(node x, node y){ //自己定义排序函数,先按位置升序排,相等时再按油量降序
if(x.a == y.a) return x.b > y.b;
return x.a < y.a;
}
int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif //sxk
int n, l, p;
while(scanf("%d", &n)!=EOF){
for(int i=0; i<n; i++) scanf("%d%d", &m[i].a, &m[i].b);
scanf("%d%d", &l, &p);
for(int i=0; i<n; i++) m[i].a = l - m[i].a; //处理读入的数据,将位置转化为据起点的位置
m[n].a = l; //方便起见,把终点也看作一个加油站
m[n].b = 0;
n ++;
sort(m, m+n, cmp); //加油站按位置排序
priority_queue<int> q;
int flag = 1;
int ans = 0, pos = 0, tank = p; //加油次数ans,车的位置pos,车上剩余油量tank
for(int i=0; i<n; i++){
int d = m[i].a - pos; //接下来要行进的距离
while(tank < d){ //不断加油,直到油量足够行驶到下一个加油站
if(q.empty()){ //未到加油站就没油了,代表不能完成任务了
flag = 0;
break;
}
tank += q.top();
q.pop();
ans ++;
}
if(!flag) break;
tank -= d;
pos = m[i].a;
q.push(m[i].b); //将途经加油站的油量放入优先级队列
}
printf("%d\n", flag ? ans : -1);
}
return 0;
}
PS:优先级队列(priority_queue)很神奇,很好用,内部用堆实现的,所以时间复杂度还是很优的~~~
POJ 2431 Expedition (贪心 + 优先级队列)
标签:
原文地址:http://blog.csdn.net/u013446688/article/details/43084317