《算法竞赛进阶指南》0x17二叉堆 POJ1456

题目链接:http://poj.org/problem?id=1456

题意是给出一些商品的价值以及过期时间,现在每天只能卖出一个商品,问卖出商品的价值总和最多是多少,贪心算法可以解决,用一个集合表示决策

将商品按照过期时间进行排序之后顺序扫描,如果过期时间大于二叉堆中的商品数量就直接放入,若等于就将最小的价值与他比较,放入较大的。

集合中的商品数量是一定小于等于当前扫描的商品的过期时间的,因为有size<=date[i-1],即判断第i-1个商品的时候保证了集合中的决策能实现,又有date[i-1]<=date[i],故结论已证。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 10010
struct node{
    int val,d;
    bool operator < (const node& a) const{
        return d<a.d;//按照过期时间进行升序排序 
    }
}a[maxn];
int n;
priority_queue<int,vector<int>,greater<int> > pq;
int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%d%d",&a[i].val,&a[i].d);
        } 
        sort(a,a+n);
        while(pq.size())pq.pop();
        for(int i=0;i<n;i++){
            if(!i){
                pq.push(a[i].val);
                continue;
            }
            if(a[i].d == (int)pq.size()){
                if(a[i].val>pq.top()){//当前商品比之前决策中的最小价值高 
                    pq.pop();
                    pq.push(a[i].val);
                }            
            }else if(a[i].d > (int)pq.size()){
                pq.push(a[i].val);
            }
        }
        int ans=0;
        while(!pq.empty()){
            ans+=pq.top();
            pq.pop();
        }
        cout<<ans<<endl;
    } 
}

 

posted @ 2020-06-18 10:54  WA自动机~  阅读(124)  评论(0编辑  收藏  举报