堆及堆的变种

堆及堆的变种

声明

参考课件和讲授来自Accelerator,分析懒得打也来自他

堆的元素删除

借用标记的思想,我们维护一个和原堆同样性质(大根,小根)的堆,每次删除就把它扔到标记堆里面
当我们需要 pop 的时候,如果堆顶元素和删除堆顶元素相同,
那么就说明这个元素是我们之前删除过的,于是我们就在删除堆里面和这个堆里面同时 pop, 然后考察下一元素。
容易发现时间复杂度和空间复杂度没有什么实质性的变化。

luogu P3545 [POI2012]HUR-Warehouse Store

我们最先想到的是能卖就卖,但是却有可能直接卖给一个人剩下的不够而 GG
为了避免这种情况,我们把已经卖掉的所有价值扔到一个堆里,每次取出堆顶的元素和当前的价值进行比较,如果堆顶的元素比他大,那就“退掉”之前的东西,换给他。
这样虽然不能使答案增加,但是可以增加库存。有一种前人栽树后人乘凉的感觉 233

因为题目没说要按顺序,所以就只用了一个结构体(看题解可以偷懒

#include<cstdio>
#include<queue>
using namespace std;
#define ll long long
const int MAX = 250000+9;

inline ll read() {
    char ch = getchar(); ll f = 1, x = 0;
    while(ch<'0' || ch>'9') {if(ch=='-') f = -1; ch = getchar();}
    while(ch>='0' && ch<='9') {x = x*10+ch-'0'; ch = getchar();}
    return x*f;
}

int n;
ll kucun;

struct time{
    ll arr, brr;//这里的arr,在day里面是第i天进货数,在p_q里面是记录的满足了第几天的客人
    bool operator < (const time& xxx) const {
        return brr < xxx.brr;//大根堆:为了取出前面花费最多的
    }
}day[MAX];
priority_queue <time> q;

int main() {
    n = read();
    for(int i = 1; i <= n; i++) day[i].arr = read();
    for(int i = 1; i <= n; i++) day[i].brr = read();
    int t = 0;//表示满足了多少人
    for(int i = 1; i <= n; i++) {
        kucun += day[i].arr;
        if(kucun >= day[i].brr) { //能买就买
            kucun -= day[i].brr;
            t++;
            time now; now.arr = i, now.brr = day[i].brr;
            q.push(now);
        } else {
            if(q.size() && q.top().brr > day[i].brr) {//不能买的时候再“退钱回去”
                kucun += q.top().brr-day[i].brr;//这波不亏
                q.pop();
                time now; now.arr = i, now.brr = day[i].brr;
                q.push(now);
            }
        }
    }
    printf("%d\n", t);
    while(!q.empty()) printf("%lld ",q.top().arr), q.pop();//里面装的都是满足了的
    printf("\n");
}

原文地址:https://www.cnblogs.com/tyner/p/11443008.html

时间: 2024-10-13 06:49:32

堆及堆的变种的相关文章

数据结构之二叉堆(构建堆,堆排序)-(七)

/* * @author Lip * @date 2015-04-23 */ public class Heap { public static void main(String[] args) { // TODO Auto-generated method stub //System.out.println((int)-1.5); int []array={4,2,7,9,3,6,1,12,10,5}; System.out.println("原始:"); printHeapByLe

C++ 堆 和 堆 分析

[摘要] 堆和栈,即是数据结构,又是分配存储空间的不同方式.在数据结构上.堆是树型层次结构,结点按keyword次序排列,经常使用的堆为二叉堆:栈是一种先进后出的数据结构.在内存分配上的堆和栈,首要差别在于申请方式不同.其次在存取速度.存储空间的大小.存储内容(一定要记住,栈中是第一条可运行语句地址.然后是各个參数.堆中头部是堆的大小描写叙述.之后有程序猿自己安排).内存中的相对位置和系统相应的响应上都各有自己差别.在C语言 的学习过程中,堆和栈即是基础也是重点. [正文] 堆栈是一个非常模糊的

SQL0973N在 &quot;&lt;堆名&gt;&quot; 堆中没有足够的存储器可用来处理语句

SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句. 解释: 已使用此堆的所有可用内存.不能处理该语句. 用户响应: 接收到此消息(SQLCODE)后就终止应用程序.修改 "<堆名称>"配置参数以增大堆大小. 例如,要更新数据库配置参数,发出如下命令: db2 update db cfg  for "<db-name>"  using "<heap-name>"

C#中的堆栈与堆(托管堆) [转自互联网]

首先堆栈和堆(托管堆)都在进程的虚拟内存中.(在32位处理器上每个进程的虚拟内存为4GB)堆栈stack : 堆栈中存储值类型.   堆栈实际上是向下填充,即由高内存地址指向地内存地址填充.   堆栈的工作方式是先分配内存的变量后释放(先进后出原则).   堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的规则不与变量的生命周期起冲突!   堆栈的性能非常高,但是对于所有的变量来说还不太灵活,而且变量的生命周期必须嵌套. 通常我们希望使用一种方法分配内存来存储数据,并且方法退出后很长一段时

堆是堆,栈归栈

堆是堆,栈归栈 在阅读以下内容之前,请了解一下几点: 第一:坚决澄清:堆是堆,栈归栈. 第二:曾经的“堆栈”再不允许重谈,简直就是扯淡! 第三:下面内容均属于从内存分配角度的阐述,不要与数据结构混淆. [1]程序的内存分配 (1)内存分配详解 一个由C/C++编译的程序占用的内存分为以下几个部分 <1>栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等. <2>堆区(heap) — 一般由程序员设计分配及释放,若程序员不释放,程序结束时可能由OS回收.可能

bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心

Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1<=Mi<=N)只. 他们希望从Si到Ei去.公交车只能座C(1<=C<=100)只奶牛.而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求.注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足. Input 第1行: 三个整数: K,N,C. 由空格隔开. 第2..

二叉堆 - 最小堆

二叉堆:一般我们拿来用的就是最大堆和最小堆. 最小堆:每个节点的值比它的左右子节点的值要大. 代码实现如下:参考Mark Allen Weiss<数据结构和算法分析>(第二版) 1 #include <cstdio> 2 #include <cstdlib> 3 4 #define MIN (1<<(sizeof(int)*8-1)) 5 6 typedef int Item; 7 typedef struct HeapStruct* heap; 8 9 s

算法导论学习之堆+堆排序+堆构成优先队列

注:堆分为最大堆和最小堆两种,下面我们讨论的堆都是指的最大堆,最小堆的性质与其是类似的. 堆数据结构是一种数组对象,可以被视为一棵完全二叉树(这棵二叉树除最后一层外,其余每层都是填满的):我们用一个数组来存储一个堆,表示堆的数组有两个属性:length[A]表示的是数组中的元素个数,headsize[A]表示堆中元素个数(也就是说数组中的元素不一定都是堆中的元素). 下面不加证明的给出一些堆的性质: 对于任何一个节点,其父节点为i/2(i>1):左儿子:2*i,右儿子:2*i+1; 对于最大堆每

Python3实现最小堆建堆算法

今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构的时候有个堆排序算法,所以顺便研究了一下“堆”结构(这里特指二叉堆). 概念 所谓二叉堆(binary heap)实际上就是一颗特殊的完全二叉树,其特殊性在于: 二叉树中所有的父节点的值都不大于/不小于其子节点: 根节点的值必定是所有节点中最小/最大的. 父节点值不大于子节点且根节点值最小称为最小堆