题目链接:http://poj.org/problem?id=2431

题意:一辆卡车需要行驶 L 距离,车上油的含量为 P,在行驶的过程中有 n 个加油站 每个加油站到终点的距离是ai,每个加油站最多给卡车加 b 单位的油;求最后到达终点需要加油的最少次数;如果不能到达,输出-1;

我们可以从起点开始算,看每次油箱中的油是否能够到达下一个加油站,如果不能就加上已经经过的加油站的所能加的最大加油量,如果能到达,就记录一下此加油站可以被加进去;因为我们每次都需要加进去最大的加油

量,所以我们可以用优先队列;来存,那么每次取出来的就是最大值;

时间复杂度是O(n*logn)

用c++中的STL:

#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define N 101000
#define INF 0xfffffff
using namespace std; int n, P, L, ans, f; struct node
{
int a,b;
} s[N]; int cmp(node n1,node n2)
{
return n1.a<n2.a;
} void slove()
{
priority_queue<int> Q;///优先队列; int pos = , i = ;///pos表示当前所在位置; while(i <= n)
{
int d = s[i].a - pos; while(Q.size() && P < d)///当不能到达下一个加油站时,要取出最大的加油量加进去;
{
int p = Q.top(); Q.pop();
P += p;
ans ++;
}
if(P >= d)
{
Q.push(s[i].b);
pos = s[i].a;
P -= d;
}
else
{
ans = -;
return ;
}
i ++;
}
} int main()
{
int i; while(scanf("%d",&n) != EOF)
{
memset(s, , sizeof(s)); ans=; for(i=; i<n; i++)
scanf("%d %d",&s[i].a, &s[i].b); scanf("%d %d", &L, &P); for(i=; i<n; i++)
s[i].a = L - s[i].a; s[i].a = L;
s[i].b = ;///把终点当成最后一个加油站处理; sort(s, s+n+, cmp); slove(); printf("%d\n", ans);
}
return ;
}

手写实现堆---优先队列;

#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define N 11000
#define INF 0x3f3f3f3f
using namespace std; int Max_Heap[N], K;///K代表Max_Heap的个数;
int p; void Push(int x)///在最大堆中插入x;
{
Max_Heap[K++] = x;///放到最后一个节点处; int t = K-; while(Max_Heap[t] > Max_Heap[t/] )///当它的值大于它的父节点的值时,要交换一下位置;
{
swap(Max_Heap[t], Max_Heap[t/]);
t = t/;
}
}
void Pop()
{
K --;///删除元素,堆中总个数减一; Max_Heap[] = Max_Heap[K];///把最后一个数放到最上面,然后一步一步往下更新堆; Max_Heap[K] = -;///防止越界,相当于建立哨兵; int t = ;///从第一个节点开始往下更新; while( Max_Heap[t] < Max_Heap[t*] || Max_Heap[t] < Max_Heap[t*+])
{
if(Max_Heap[t] < Max_Heap[t*] && Max_Heap[t*] > Max_Heap[t*+])
{///左儿子大于它时,并且满足左儿子大于右儿子,让左儿子上去;
swap(Max_Heap[t], Max_Heap[t*]);
t = t*;
}
else
{
swap(Max_Heap[t], Max_Heap[t*+]);
t = t* + ;
}
}
} int n, P, L, ans, f; struct node
{
int a,b;
} s[N]; int cmp(node n1,node n2)
{
return n1.a<n2.a;
} void slove()
{
memset(Max_Heap, -, sizeof(Max_Heap)); Max_Heap[] = INF; K = ; int pos = , i = ; while(i <= n)
{
int d = s[i].a - pos; while(K!= && P < d)
{
int p = Max_Heap[];
Pop();
P += p;
ans ++;
}
if(P >= d)
{
Push(s[i].b);
pos = s[i].a;
P -= d;
}
else
{
ans = -;
return ;
}
i ++;
}
} int main()
{
int i; while(scanf("%d",&n) != EOF)
{
memset(s, , sizeof(s)); ans=; for(i=; i<n; i++)
scanf("%d %d",&s[i].a, &s[i].b); scanf("%d %d", &L, &P); for(i=; i<n; i++)
s[i].a = L - s[i].a; s[i].a = L;
s[i].b = ; sort(s, s+n+, cmp); slove(); printf("%d\n", ans);
}
return ;
}

Expedition---poj2431(优先队列-堆的实现)的更多相关文章

  1. POJ2431 Expedition(排序+优先队列)

    思路:先把加油站按升序排列. 在经过加油站时.往优先队列里增加B[i].(每经过一个加油站时,预存储一下油量) 当油箱空时:1.假设队列为空(能够理解成预存储的油量),则无法到达下一个加油站,更无法到 ...

  2. 【POJ - 2431】Expedition(优先队列)

    Expedition 直接中文 Descriptions 一群奶牛抓起一辆卡车,冒险进入丛林深处的探险队.作为相当差的司机,不幸的是,奶牛设法跑过一块岩石并刺破卡车的油箱.卡车现在每运行一个单位的距离 ...

  3. POJ2431 优先队列+贪心 - biaobiao88

    以下代码可对结构体数组中的元素进行排序,也差不多算是一个小小的模板了吧 #include<iostream> #include<algorithm> using namespa ...

  4. Java学习笔记--PriorityQueue(优先队列)(堆)

    PriorityQueue(优先队列)实际上是一个堆(不指定Comparator时默认为最小堆)队列既可以根据元素的自然顺序来排序,也可以根据 Comparator来设置排序规则.队列的头是按指定排序 ...

  5. c++优先队列(堆)

    1.最小堆.最大堆 priority_queue<int,vector<int>,greater<int> > f; //最小堆(后面的数逐渐greater) pr ...

  6. POJ 2431 Expedition (优先队列+贪心)

    题目链接 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. ...

  7. poj 2431 Expedition 贪心+优先队列 很好很好的一道题!!!

    Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10025   Accepted: 2918 Descr ...

  8. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

  9. POJ 2431 Expedition(优先队列、贪心)

    题目链接: 传送门 Expedition Time Limit: 1000MS     Memory Limit: 65536K 题目描述 驾驶一辆卡车行驶L单位距离.最开始有P单位的汽油.卡车每开1 ...

随机推荐

  1. bowtie2-inspect 根据bowtie2的索引取得fasta 序列

    今天运行tophat2的时候看到下面这条记录: [2016-02-27 11:40:03] Checking for reference FASTA file Warning: Could not f ...

  2. v$Session详解

    从Oracle10gR1开始,Oracle在V$SESSION中增加关于等待事件的字段,实际上也就是把原来V$SESSION_WAIT视图中的所有字段全部整合到了V$SESSION视图中,开始的时候我 ...

  3. jquery获取html元素的绝对位置和相对位置的方法

    绝对位置坐标: 代码如下: $("#elem").offset().top$("#elem").offset().left 相对父元素的位置坐标: 代码如下: ...

  4. 验证手机号码的JS方法

    function Checkreg() { //验证电话号码手机号码,包含153,159号段 if (document.form.phone.value=="" && ...

  5. linux数据盘分区以及格式化

    首先切换到root账户下  sudo -i 手动格式化 请根据以下步骤对数据盘进行分区以及格式化,并挂载分区使数据盘可用. 注:执行以下命令时,请注意修改数据盘符,可以使用”fdisk -l”查看盘符 ...

  6. docker 配置文件:/etc/docker/daemon.json

    /etc/docker/daemon.json 是 docker 的配置文件,默认是没有的,需要我们手动创建,可配置项如下: [root@localhost ~]$ vim /etc/docker/d ...

  7. Centos下Nagios的安装与配置

    一.Nagios简介 Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报 ...

  8. NGUI屏幕自适应(转)

      屏幕自适应 NGUI可以比较方便的实现屏幕自适应,但是它的官方教程里面针对这个问题没有详细的教程,所以可能在实现的时候会走比较多的弯路.以下是我在开发过程中找到的一个比较方便的实现方法. 主要组件 ...

  9. SPI接口功能描述

  10. nginx 重复提交 重复请求问题

    我遇到的奇葩问题. 后台使用的是nginx + tomcat 前端页面确实只发送了一个ajax请求到后台. 后台却接收到了两条请求! 百度了一下,说是因为nginx负载均衡,一个请求超时后会重复发送一 ...