P3093 [USACO13DEC]牛奶调度Milk Scheduling - 贪心+二叉堆

传送门

思路:一个贪心策略就是“在不挤超过截至时间的奶牛的前提下,尽量挤奶量大的奶牛”。So我们将奶牛按截至日期从小到大排序,对于每个截至时间t,将所有截至时间为t的奶牛的奶量加入一个大根堆,只留下前t大的数,剩下的直接删去。由于priority_queue没有clear函数,所以我手写了一个堆。。。(请不要问我为什么不用小根堆,每次弹出前size()-t个数,但这样做会WA得很惨。。。)

AC Code:(代码略鬼畜,但我觉得应该没多少人看我这博客吧。。)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10000+10;
struct node{
    int d,g;//d[]=deadline g[]=gain
}a[N];
bool cmp(const node a,const node b){
    return a.d<b.d;
}
int heap[N],siz;
void up(int p){//向上维护大根堆
    while(p>1){
        //p=子节点 p/2=父节点
        if(heap[p]>heap[p/2]) { //子节点大于父节点 不满足大根堆性质
        //小根堆将>改为<即可
            swap(heap[p],heap[p/2]);
            p/=2;//向上维护大根堆
        }
        else break;//满足大根堆要求
    }
}
void insert(int x){//向堆中插入元素
    heap[++siz]=x;
    up(siz);
}
int top(){//返回堆顶元素
    return heap[1];
}
void down(int p){//向下维护大根堆
    int s=p<<1;//儿子编号 初始为左儿子
    while(s<=siz){
        if(s<siz&&heap[s]<heap[s+1]) s++;//将较大的儿子换为父节点
        if(heap[s]>heap[p]){
            swap(heap[s],heap[p]);
            p=s,s=p<<1;//父节点变为较大的儿子,更新儿子编号
        }
        else break;
    }
}
void pop(){//弹出堆顶元素
    heap[1]=heap[siz--];//将堆顶元素换为堆末尾元素,然后删去末尾,避免直接删除堆顶的复杂操作
    down(1);
}
int tmp[N],tot;
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].g,&a[i].d);
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        int T=a[i].d;insert(a[i].g);
        while(a[i+1].d==T){
            insert(a[i+1].g);i++;
        }
        if(siz>T) {
            for(int i=1;i<=T;i++) tmp[++tot]=top(),pop();
            siz=0;
            for(int i=1;i<=tot;i++) insert(tmp[i]);
            tot=0;
        }
    }
    int ans=0;
    while(siz) ans+=top(),pop();
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Loi-Brilliant/p/9419450.html

时间: 2024-11-08 13:44:38

P3093 [USACO13DEC]牛奶调度Milk Scheduling - 贪心+二叉堆的相关文章

P3093 [USACO13DEC]牛奶调度Milk Scheduling——贪心

其实可以用dp   f[j]表示到j时间最大的收益 #include<bits/stdc++.h>using namespace std;int n,f[100000];struct node{ int d,g;}a[1000000];bool cmp(node a,node b){ return a.d<b.d;}int main(){ cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].g>>a[i].d; }

洛谷P3093 [USACO13DEC]牛奶调度Milk Scheduling

题目描述 Farmer John has N cows that need to be milked (1 <= N <= 10,000), each of which takes only one unit of time to milk. Being impatient animals, some cows will refuse to be milked if Farmer John waits too long to milk them. More specifically, cow

【转】二叉堆与优先队列

目录 1.插入 2.删除 3.查询 1.堆排序 2.用两个堆来维护一些查询第k小/大的操作 中位数 3.利用堆来维护可以“反悔的贪心” 如题,二叉堆是一种基础数据结构 事实上支持的操作也是挺有限的(相对于其他数据结构而言),也就插入,查询,删除这一类 对了这篇文章中讲到的堆都是二叉堆,而不是斜堆,左偏树,斐波那契堆什么的 我都不会啊 更新概要: 无良博主终于想起来要更新辣 upd1:更新5.2.2-对于该子目所阐述的操作“用两个堆来维护一些查询第k小/大的操作”更新了一道例题-该操作对于中位数题

集训队7月31日(二叉堆和哈曼夫树)

今天上午学习了二叉堆和哈曼夫树,算法竞赛指南80~92页. 先说一下我对二叉堆和哈曼夫树的理解,二叉堆分为大根堆,小根堆,而哈曼夫树就是二叉堆的一种表现形式,在解决一些权值带深度的一些问题上是一个良好的思路,简而言之,这两个东西可以表示为维护一个优先队列. 学了这两个知识,写了三个题. 1.二叉堆+贪心+链表 https://www.cnblogs.com/2462478392Lee/p/11279484.html多校 2.哈夫曼树 https://www.cnblogs.com/2462478

二叉堆(binary heap)

堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.堆即为解决此类问题设计的一种数据结构. 本文地址:http://www.cnblogs.com/archimedes/p/binary-heap.html,转载请注明源地址. 逻辑定义 n个

算法—二叉堆

实现栈或是队列与实现优先队列的最大不同在于对性能的要求.对于栈和队列,我们的实现能够在常数时间内完成所有操作:而对于优先队列,插入元素和删除最大元素这两个操作之一在最坏情况下需要线性时间来完成.我们接下来要讨论的基于数据结构堆的实现能够保证这两种操作都能更快地执行. 1.堆的定义 数据结构二叉堆能够很好地实现优先队列的基本操作.在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素.相应地,这些位置的元素又至少要大于等于数组中的另两个元素,以此类推.如果我们将所有元素画成一棵二叉树,将每

二叉堆 - 最小堆

二叉堆:一般我们拿来用的就是最大堆和最小堆. 最小堆:每个节点的值比它的左右子节点的值要大. 代码实现如下:参考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

Bestcoder4——Happy Three Friends(二叉堆)

本文出自:http://blog.csdn.net/svitter Happy Three Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Dong-hao , Grandpa Shawn , Beautful-leg

堆排序:什么是堆?什么是最大堆?二叉堆是什么?堆排序算法是怎么样的?PHP如何实现堆排序?

本文标签:  堆排序 php php算法 堆排序算法 二叉堆 数据结构 REST   服务器 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个"优秀"的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么是最大堆 堆中每个父节点的元素值都大于等于其孩子结点(如果存在),这样的堆就是一个最大堆 因此,最大堆中的