堆 (优先队列)举例

*/-->

pre.src {background-color: Black; color: White;}

堆 (优先队列)举例

题目:
你需要驾驶一辆卡车行驶 l 单位距离。最开始的时候,卡车上有 p 单位的汽油。卡车每开 1 单位距离需要消费 1 单位的汽油。如果在途中汽车上的汽油耗尽,卡车就无法继续前行,因而无法到达终点。在途中一共有 n 个加油站。第 i 个加油站在距离起点 ai 单位距离的地方,最多可以给卡车加 bi 单位汽油。假设卡车的燃料箱的容量是无限大的,无论加多少油都没有问题。那么问卡车是否能到达终点?如果可以,最少需要加多少汽油?如果可以到达终点,输出最少的加油次数,否则输出 -1。

示例:
n = 4
l = 25
p = 10
a = { 10, 14, 20, 21 }
b = { 10, 5, 2, 4 }

输出 2

// CreateTime: 2015-04-08 13:27:16

#include <iostream>
#include <queue>

using namespace std;

// priority_queue <int, vector<int>, greater<int> > que;  // 最小堆
priority_queue<int> que;        // 最大堆
int l;                          // 路的长度
int n;
const int maxn = 10005;
int a[maxn];                    // 加油站到起点的距离
int b[maxn];                    // 加油站可以加的油
int ans;
int p;                          // 刚开始的时候汽车有多少油

void solve() {
    ans = 0;
    int pos = 0;
    int tank = p;               // 目前的油

    for (int i = 0; i <= n; i++) {
        int d = a[i]- pos;
        while (tank < d) {      // 需要加油
            if (que.empty()) {
                cout << "-1" << endl;
                return;
            }

            tank += que.top();
            que.pop();
            ans++;
        }

        tank = tank - d;              // 不需要继续加油了
        que.push(b[i]);
        pos = a[i];
    }
}

int main(void) {
    cin >> n >> l >> p;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> b[i];
    }
    a[n] = l;
    b[n] = 0;
    solve();
    cout << ans << endl;

    return 0;
}
时间: 2024-10-08 20:45:14

堆 (优先队列)举例的相关文章

纯数据结构Java实现(6/11)(二叉堆&amp;优先队列)

堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). 但是二叉堆,需要满足一些特殊性质: 其一.二叉堆一定是一棵完全二叉树 (完全二叉树可以用数组表示,见下面) 完全二叉树缺失的部分一定是在右下方.(每层一定是从左到右的顺序优先存放) 完全二叉树的结构,可以简单理解成按层安放元素的.(所以数组是不错的底层实现) 其二.父节点一定比子节点大 (针对大顶堆

堆-优先队列

堆-优先队列 前置知识:二叉树. 参考资料 暂无 堆就是优先队列,可以用来解决动态区间查询最值问题. 堆就是一个完全二叉树,可以插入节点,删除根节点(也可以删除特定节点). 为了方便,普通的堆节点 \(i\) 的父亲就是 \([i\div2]\) (\([x]\) 表示不超过 \(x\) 的最大整数). 节点 \(i\) 的左儿子是 \(i\times2\),右儿子是 \(i\times2+1\). 对于一个大顶堆: 每次插入节点的时候,就把节点插在完全二叉树的最后,如果它比它的父亲节点大,就把

堆(优先队列)求huffman WPL

huffman编码中WPL等于没个结点到根结点的距离乘结点权值的总和,但我们也可以用另一种方法求WPL:如果huffman树只有一个结点,则WPL为根结点权值,否则WPL等于除了根结点以外的所有结点的权值之和. 我们可以用优先队列/堆实现这个过程: 1 //用优先队列求huffman编码中的WPL 2 #include <iostream> 3 using std::cin; 4 using std::cout; 5 using std::endl; 6 using std::swap; 7

【bzoj2151】种树(堆/优先队列+双向链表)

题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 这道题因为优先队列不怎么会用,而且手写堆的代码也不长,也想复习一下手写堆的写法……结果……WAWAWAWAW……看来我对堆的认识还是太浅薄了…… 这道题,如果没有限制不能选相邻的两个位置,那就肯定是贪心地选择m个美观度最大的位置种树.然而这里加了限制,那么我们可以注意到,如果一个美观度比较大的位置不被选上,一定是因为它两边的位置都被选了. 于是我们可以把n个美观度压进一个堆里,每

Running Median POJ - 3784 (对顶堆/优先队列)

For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far. Input The first line of input contains a single int

升序堆和降序堆(优先队列) 洛谷1801

1 // 洛谷1801 2 // 一个升序堆,一个降序堆 3 // 降序堆维护序列的前i个最小值 4 // 插如元素的时候,如果x小于降序堆最大值,则替换,并将最大值插入升序堆:否则,直接插入升序堆 5 // 每次输出升序堆的最小值即可 6 7 8 #include <bits/stdc++.h> 9 using namespace std; 10 #define LL long long 11 typedef pair<int,int> pii; 12 const int inf

堆(优先队列)模板

包含向上.向下两种维护方向,方便手动维护堆中单个元素(STL的priority_queue和make_heap没有这种功能T_T) namespace heap{    #define p(x) ((x) >> 1)    #define l(x) ((x) << 1)    #define r(x) (((x) << 1) + 1)    #define maxn ((int)1e5)    template <typename T>        str

P1168 中位数[堆 优先队列]

题目描述 给出一个长度为NNN的非负整数序列AiA_iAi?,对于所有1≤k≤(N+1)/21 ≤ k ≤ (N + 1) / 21≤k≤(N+1)/2,输出A1,A3,…,A2k−1A_1, A_3, …, A_{2k - 1}A1?,A3?,…,A2k−1?的中位数.即前1,3,5,…1,3,5,…1,3,5,…个数的中位数. 输入输出格式 输入格式: 第1行为一个正整数N,表示了序列长度. 第2行包含N个非负整数Ai?(Ai?≤109). 输出格式: 共2(N+1)/2行,第iii行为A1

最大堆/最小堆/优先队列 实现代码(c++)

自我感觉代码写的比较乱,这方面要好好注意一下. 总结: 1.在使用vector<int>::size_type 类似的类型时,千万要注意循环的条件判断,很容易发生溢出的危险!所以我最后很懒的选择使用int  - -. 2.下标表示和元素个数表示之间的细微差别.下标之间的变换关系: 父节点 parent(i)=(i-1)/2; 左孩子 left(i)=2*i+1;右孩子 right(i)=2*i+2 class Max_Heap{ typedef int index; public: Max_H