zoukankan      html  css  js  c++  java
  • stl-优先队列

    优先队列定义:普通队列遵循先进先出的原则,只能从尾部插入,从头部弹出。优先队列特性,队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。

    1.头文件#include<queue>

    2.声明操作:

    priority_queue<int> q;                 //元素按照从大到小的顺序出队

    priority_queue<int,vector<int>, greater<int> > q;  //元素按照从小到大的顺序出队

    3.empty()  //若空,返回真

    4.size()   //返回元素个数

    5.push(a)  //元素a入队

    6.top()    //返回队头元素//普通队列返回队头元素就是front()

    7.结构体优先队列,利用重载符号进行优先排序,举例:hdu1873

    struct patient
    {
        int id;///编号
        int val;///优先级
    };
    
    bool operator<(patient p1,patient p2)
    {
        if(p1.val==p2.val)
            return p1.id>p2.id;
        return p1.val<p2.val;
    }///优先级高的排在前面,重载操作符出来效果和自定义函数相反
    priority_queue<patient>que;

    运用题目(NYOJ55)

    题目描述:

      小明很想吃果子,正好果园果子熟了。在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。小明决定把所有的果子合成一堆。 因为小明比较懒,为了省力气,小明开始想点子了:
      每一次合并,小明可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。小明在合并果子时总共消耗的体力等于每次合并所耗体力之和。
      因为还要花大力气把这些果子搬回家,所以小明在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。
      例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以小明总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
    输入描述:
    第一行输入整数N(0< N< =10)表示测试数据组数。接下来每组测试数据输入包括两行,第一行是一个整数n(1<=n<=12000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
    输出描述:
    每组测试数据输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。
    样例输入:

    1
    3
    1 2 9

    样例输出:

    15

    AC代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    priority_queue<int,vector<int>, greater<int> > q;
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n,x,a,b;
            ll sum=0;///要用long long储存
            scanf("%d",&n);
            while(n--)
            {
                scanf("%d",&x);
                q.push(x);
            }
            if(n==1)
                printf("%d
    ",sum);
            else
            {
                while(q.size())
                {
                    a=q.top();
                    q.pop();
                    b=q.top();
                    q.pop();///消耗体力等于两堆的重量之和,加到sum里,
                    sum=sum+a+b;
                    if(!q.empty())
                    q.push(a+b);///弹出a和b,再压进新的一堆,其重量为a+b
                    ///如果是最后两个元素,弹出后合并成一堆,此时队空,直接结束
                }
                printf("%lld
    ",sum);}
            }
        return 0;
    }
  • 相关阅读:
    SQL 开发任务超 50% !滴滴实时计算的演进与优化
    Windows中如何使用命令行执行Kettle作业Job
    Kettle增量更新设计技巧
    oracle数据库查询全系整理
    Kettle基本概念 之 Kettle设计模块
    ETL-Kettle学习笔记(入门,简介,简单操作)
    SQL Server 索引——的创建、删除、何时使用、索引查询语句
    I/O端口与I/O内存
    设置用户id和设置组id
    进程控制
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/9557740.html
Copyright © 2011-2022 走看看