zoukankan      html  css  js  c++  java
  • 0x17二叉堆之超市

    题目链接:https://www.acwing.com/problem/content/147/

    容易想到一个贪心策略:在最优解中,对于每个时间(天数) t,应该在保证不卖出过期商品的前提下,尽量卖出利润前t大的商品。因此,我们可以依次考虑每个商品,动态维护一个满足上述性质的方案。
    详细地说,我们把商品按照过期时间排序,建立一个初始为空的小根堆 (节点权值为商品利润),然后扫描每个商品:
    1.若当前商品的过期时间(天数) t等于当前堆中的商品个数,则说明在目前方案下,前t天已经安排了t个商品卖出。此时,若当前商品的利润大于堆顶权值(即已经安排的t个商品中的最低利润),则替换掉堆顶(用当前商品替换掉原方案中利润最低的商品)。

    2.若当前商品的过期时间(天数)大于当前堆中的商品个数,直接把该商品插入堆。

    3.若当前商品的过期时间(天数)小于当前堆中商品的个数,哦!!!不可能,因为在第一种情况中,若当前商品的过期时间(天数) t等于当前堆中的商品个数,我们就会替换掉商品。
    最终,堆里的所有商品就是我们需要卖出的商品,它们的利润之和就是答案。该算法的时间复杂度为O(N logN)。

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<queue>
    using namespace std;
    struct node{
        int val;
        int time;
    
    }nodes[10050];
    bool operator <(const node &a, const node &b) {
        return a.time<b.time;
    }
    int main(){
        int n;
        while (cin>>n) {
            for (int i = 1; i <= n; ++i) {
                cin>>nodes[i].val>>nodes[i].time;
            }
            sort(nodes+1,nodes+n+1);
    
            priority_queue<int,vector<int>, greater<int> > q;
            for (int i = 1 ; i <=n; ++i) {
                int currentDay=nodes[i].time;
                if (currentDay>q.size()) {
                    q.push(nodes[i].val);
                }else {
                    int vals=q.top();
                    if(vals<nodes[i].val){
                        q.pop();
                        q.push(nodes[i].val);
                    }
                }
            }
            int ans=0;
            while (!q.empty()) {
                ans+=q.top();
                q.pop();
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    

      

    加油啦!加油鸭,冲鸭!!!
  • 相关阅读:
    c++看题
    理想化
    thin mission
    编程时 和 thinking
    tiny mission 2021 10 20
    A Magic Lamp HDU
    Poj 3370
    鸽巢原理(抽屉原理)
    Miller-Rabin质数测试
    Nim or not Nim? HDU
  • 原文地址:https://www.cnblogs.com/clarencezzh/p/10793474.html
Copyright © 2011-2022 走看看