Acwing 145.超市(二叉堆 & 贪心)

题目链接

题目的大意就是每天可以卖一种商品,但每个商品都有自己的保质期,求最大的收益。转换一下,就是每天都尽量选择最大的商品卖,这里有两种解决方法,一种是贪心,一种是是二叉堆。
很容易想到这题的贪心解法,先对商品按价格进行排序,然后再选择在第几天卖掉它,因为我们要尽可能卖掉更多的商品,因此要选择尽量靠后的时间卖掉它。
下面看代码

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int vis[N];
int n;
struct node{
    
    
    int vi;
    int day;
}goods[N];

bool cmp(node x, node y){
    
    
    if(x.vi == y.vi) return x.day < y.day;
    else return x.vi > y.vi;
}
int main(){
    
    
    while(scanf("%d", &n) != EOF){
    
    
        memset(vis, 0, sizeof vis);
        for(int i = 1; i <= n; i++) cin >> goods[i].vi >> goods[i].day;
        sort(goods+1, goods+n+1, cmp);
        int sum = 0;
        for(int i = 1; i <= n; i++){
    
    
            int f = 0;
            for(int j = goods[i].day; j >= 1; j--){
    
    
                if(!vis[j]){
    
    
                    vis[j] = 1;
                    f = 1;
                    break;
                }
            }
            if (f == 1) sum += goods[i].vi;
        }
        cout << sum << endl;
    }
}

下面重点介绍利用二叉堆的写法。
简介:
二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。

在stl标准库中就有二叉堆可以直接调用,就是priority_queue,这个容器默认是递减的大根堆,因此要让序列递增我们只要进行重载一下,利用greater就行了。知道这个之后接下来要怎么用呢?我们可以把当前容器内的当做我们已经选择要卖掉的,然后对每一个放进来的商品进行判断,当然先把商品按保质期从小到大排序,如果当前商品的保质期还小于等于容器的体积,那么可以直接放入,如果当前的商品的保质期大于容器的体积,那么我们就将容器中最小的出队,这样就可以维护堆中的和最大。

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef pair<int, int> PII;
int n;
int main(){
    
    
    while(cin >> n) {
    
    
        vector<PII> products(n);
        for (int i = 0; i < n; i ++) cin >> products[i].second >> products[i].first;
        
        sort(products.begin(), products.end());
        
        priority_queue<int, vector<int>, greater<int>> heap;
        for (int i = 0; i < n; i ++) {
    
    
            heap.push(products[i].second);
            if (heap.size() > products[i].first) heap.pop();
        }
        int res = 0;
        while (heap.size()) res += heap.top(), heap.pop();
        cout << res << endl;
    }
}

猜你喜欢

转载自blog.csdn.net/kaka03200/article/details/106460138