POJ 2431 - Expedition ( 优先队列 )

题意

一辆车要行驶长L的路, 每走单位长度为1的路就消耗单位数量为1的汽油
开车前有P的油, 给出N对数字表示加油站, 第一个数为加油站距离终点距离( 这里一开始读题没仔细读 ) , 第二个数是加油站供给的油量

思路

学习白书的思路
优先队列 priority_queue
存下0 ~ n号加油站的信息 A[] ( 加油站距离起点的位置 ) B[] ( 加油站供给油量 )
因为要求最少加油次数, 具体操作为 : 每次计算出加油站之间相距的距离, 若油量不够, 则取出优先队列的队首(历经过的加油站中油量最大的), 然后将下次抵达的加油站油量存入优先队列
如果队列为空则无解, 输出-1

AC代码

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>
#define mst(a) memset(a, 0, sizeof(a));

using namespace std;
const int maxn = 10000 + 100;
struct stops{
    int x, y;
}s[maxn];

int A[maxn];  //加油站位置
int B[maxn];  //加油站容量
int L, P, n;
priority_queue<int> que;

bool cmp( struct stops a, struct stops b ){
    return a.x > b.x;
}

void solve()
{
    int cnt = 0;
    int d, pos = 0, you = P;
    for( int i = 0; i < n; i++ ){
        d = A[i] - pos;
        while( you - d < 0 ){
            if( que.empty() ){
                printf("-1\n");
                return;
            }
            you += que.top();
            que.pop();
            cnt++;
        }
        you -= d;
        que.push(B[i]);
        pos = A[i];
    }
    printf("%d\n",cnt);
}

int main()
{
    while( ~scanf("%d",&n) ){
        mst(A);
        mst(B);
        mst(s);
        for( int i = 0; i < n; i++ )
            scanf("%d%d",&s[i].x, &s[i].y);
        sort(s, s + n, cmp);
        scanf("%d%d",&L, &P);
        for( int i = 0; i < n; i++ )
            A[i] = L - s[i].x, B[i] = s[i].y;
        A[n] = L;  // 为了方便处理 标记终点为最后一个加油站
        B[n] = 0;
        n += 1;  //别忘记加油站数量+1
        solve();
        while( !que.empty() )
            que.pop();
    }
    return 0;
}
posted @ 2018-03-13 20:04  JinxiSui  阅读(165)  评论(0编辑  收藏  举报