• CJOJ 2482 【POI2000】促销活动(STL优先队列,大根堆,小根堆)


    CJOJ 2482 【POI2000】促销活动(STL优先队列,大根堆,小根堆)

    Description

    促销活动遵守以下规则:

    • 一个消费者 —— 想参加促销活动的消费者,在账单下记下他自己所付的费用,他个人的详细情况,然后将账单放入一个特殊的投票箱。
    • 当每天促销活动结束时,从投票箱中抽出两张账单:

    第一张被抽出的账单是金额最大的账单

    然后被抽出的是金额最小的账单,对于付了金额最大账单的这位消费者,将得到一定数目的奖金,其奖金数等于他账单上的金额与选出的最小金额的差。
    为了避免一个消费者多次获奖,根据上面所抽出的两张账单都不返回到投票箱,但是剩下的账单还继续参加下一天的促销活动。

    超市的售出额是巨大的,这样可以假定,在每天结束,拿出数额最大账单和数额最小账之前,在投票箱内就已经至少存在了 2 张账单。你的任务是去计算每天促销活动投进投票箱的账单数额的基本信息。在整个活动中开销总数。

    本题中约定:
    整个活动持续了 N 天 (N<=5000) 。 第 i 天放入的帐单有 a[i] 张, a[i]<=10^5 。且 sigma(a[1]...a[n])<=10^6 。 每一天放入的帐单的面值均 <=10^6 。

    Input

    第一行是一个整数 n ( 1 <= n <= 5000 ),表示促销活动历时的天数。
    以下的 n 行,每行包含若干由空格分隔的非负整数。第 i+1 行的数表示在第 i 天投入箱子的账单金额。每行的第一个数是一个整数 k ( 0 <= k <= 10^5 ), 表示当日账单的数目。后面的 k 个正整数代表这 k 笔账单的金额,均小于10^6 。
    整个活动中涉及到的账单笔数不会超过 10^6 。

    Output

    输出唯一一行是一个整数,等于整个促销活动中应该付出的奖金总额。

    Sample Input

    5
    3 1 2 3
    2 1 1
    4 10 5 5 1
    0
    1 2

    Sample Output

    19

    Http

    CJOJ:http://oj.changjun.com.cn/problem/detail/pid/2482

    Source

    STL,优先队列

    题目大意

    一个商场搞促销活动n天,每天选出最高账单和最低账单,求所有最高账单-最低账单的总和。

    解决思路

    这道题是优先队列的运用。分别维护两个优先队列,一个最小值优先,一个最大值优先,每次弹出队首元素即可。需要注意的是,一个元素是在两个队列中同时存在的,而有可能在这个队列中弹出去了,而在另一个队列中还没有,所以要用一个Cnt数组统计一下每个元素出现的次数,若某次发现队首元素的Cnt已经为0了,则说明已经在另外一个队列中弹出,将重复的去除即可。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    
    const int maxN=5001;
    const int inf=2147483647;
    
    int n;
    priority_queue<int,vector<int>,less<int> > Q1;//大的优先
    priority_queue<int,vector<int>,greater<int> > Q2;//小的优先
    int Cnt[1000001]={0};//统计每一种金额的次数
    
    int main()
    {
        int K;
        int value;
        int Ans=0;
        cin>>n;
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&K);
            for (int j=1;j<=K;j++)
            {
                scanf("%d",&value);
                Cnt[value]++;
                Q1.push(value);
                Q2.push(value);
            }
            while (Cnt[Q1.top()]==0)//如果这种金额次数已经没有了,说明在另一个优先队列中已经弹出直接去掉即可
                Q1.pop();
            while (Cnt[Q2.top()]==0)//与上面同理
                Q2.pop();
            Ans=Ans+Q1.top()-Q2.top();
            //cout<<Q1.top()<<" "<<Q2.top()<<endl;
            Cnt[Q1.top()]--;
            Cnt[Q2.top()]--;
            Q1.pop();
            Q2.pop();
        }
        cout<<Ans<<endl;
        return 0;
    }
    
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    反素数(暴力)
    More Divisors(反素数)
    CodeForces
    Binary Tree(二叉树+思维)
    Friendship of Frog(水题)
    内网jenkins如何配置gitlab自动拉取代码打包
    配置git使用ssh方式克隆gitlab的代码
    centOS7创建python虚拟环境
    CentOS7下安装JDK
    centOS安装python3 以及解决 导入ssl包出错的问题
  • 原文地址:https://www.cnblogs.com/SYCstudio/p/7137746.html
Copyright © 2020-2023  润新知