poj2431 优先队列

poj2431
题意:给你一辆有 P 单位油的卡车,让你开它走 L 单位距离到达小镇,每一单位距离消耗 1 单位油。告诉你沿途有 N 个加油站,每个加油站离小镇有 Ai 单位距离,在加油站中你将得到 Bi 单位的油。 问你若想到达城市你最少加油几次。

数据:是先给你加油站个数 N,之后是 N 个加油站的参数,再然后是 L 与 P 。并且加油站参数 Ai 是离小镇有多远,并不是离起点有多远。还有一点 N 个加油站不是按距离给的。。所以要先排序才可以。。。

思路:用优先队列就可以很简单地解决了。枚举从近到远(距起点)的 N 个加油站,若到第 i 个时仍有油或刚刚用好就将该加油站参数加进队列,若不是则将队列中的top取来加油P中再比较再将这个加入队列中。。。队列中的加油站都是已经经过的,那么我们就取油量最大的,且没有加过油的加油站加油就是此时的最优解啦。。。。

代码实现:

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

struct node
{
    int num;
    int dis;
    friend bool operator < (node a, node b)
    {
        return a.num < b.num;
    }
}tem, now_oil, oil[11000];
priority_queue<struct node> q;
int comp(node a, node b)
{
    return a.dis > b.dis;
}

int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        int ans = 0;

        for(int i = 0; i < n; i++)
        {
            scanf("%d%d", &oil[i].dis, &oil[i].num);
        }
        sort(oil, oil+n, comp);

        int l, p;
        scanf("%d%d", &l, &p);

        for(int i = 0; i <= n; i++)
        {
            if(ans == -1) break;

            if(i < n)
            {
                now_oil.dis = l - oil[i].dis;
                now_oil.num = oil[i].num;
            }
            else
                now_oil.dis = l;

            while(now_oil.dis > p)
            { 
                if(q.empty())
                {
                    ans = -1;
                    break;
                } 
                tem = q.top();
                q.pop();
                ans++;
                p += tem.num;
            }

            q.push(now_oil);
        }

        while(!q.empty()) q.pop();
        printf("%d\n", ans);
    }
    return 0;
}

若有错,请大家多多指教啦^ ^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值