poj 1456 Supermarket 贪心+优先队列

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

Description

A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precisely one unit of time for being sold. A selling schedule is an ordered subset of products Sell ≤ Prod such that the selling of each product x∈Sell, according to the ordering of Sell, completes before the deadline dx or just when dx expires. The profit of the selling schedule is Profit(Sell)=Σx∈Sellpx. An optimal selling schedule is a schedule with a maximum profit. 
For example, consider the products Prod={a,b,c,d} with (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2), and (pd,dd)=(30,1). The possible selling schedules are listed in table 1. For instance, the schedule Sell={d,a} shows that the selling of product d starts at time 0 and ends at time 1, while the selling of product a starts at time 1 and ends at time 2. Each of these products is sold by its deadline. Sell is the optimal schedule and its profit is 80. 

poj 1456 Supermarket 贪心+优先队列


Write a program that reads sets of products from an input text file and computes the profit of an optimal selling schedule for each set of products. 

Input

A set of products starts with an integer 0 <= n <= 10000, which is the number of products in the set, and continues with n pairs pi di of integers, 1 <= pi <= 10000 and 1 <= di <= 10000, that designate the profit and the selling deadline of the i-th product. White spaces can occur freely in input. Input data terminate with an end of file and are guaranteed correct.

Output

For each set of products, the program prints on the standard output the profit of an optimal selling schedule for the set. Each result is printed from the beginning of a separate line.

Sample Input

4  50 2  10 1   20 2   30 1

7  20 1   2 1   10 3  100 2   8 2
   5 20  50 10

Sample Output

80
185

Hint

The sample input contains two product sets. The first set encodes the products from table 1. The second set is for 7 products. The profit of an optimal schedule for these products is 185.

 

这道题有很多解法,这里就介绍一种:

贪心+优先队列:显然在第t天的时候 要在不变质的情况下卖掉利润前t大的,用优先队列维护就行。具体的就是 ,先按过期时间从先到后,再按利润从大到小排序,优先队列按利润从小到大排,然后一一枚举。 对于每一个商品  如果商品过期天数等于队列的大小,则判断队头的利润和该商品的利润大小关系,如果该商品的利润大于队头的利润 ,则队头出队(因为有利润更大的满足条件的商品),该商品入队。 当该商品过期天数大于队列的大小时候,该商品在此时显然满足条件,可以直接入队。

代码如下:

/// 16MS 还是挺快的
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 1e4+100;

inline int read() {///快读
    int X = 0,w = 0; char ch = 0;
    while(!isdigit(ch)) {w |= ch == '-';ch = getchar();}
    while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch=getchar();
    return w ? -X : X;
}

struct node{
    int p,d;
    bool friend operator < (node a,node b){///优先队列利润小排前面,因为它是最需要替换的(替换后利润更大)
        return a.p>b.p;
    }
}t[maxn];

bool cmp(node x,node y){///天数是第一关键词,利润是第二关键词
    return x.d<y.d||(x.d == y.d && x.p>y.p);
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        priority_queue<node>Q;
        for(int i = 1; i <= n; i++)
            t[i].p = read(),t[i].d = read();
        sort(t+1,t+1+n,cmp);
        for(int i = 1; i <= n; i++)
            if(t[i].d>Q.size())///当前商品天数大于维护的队列,直接入队(在当前状态下它肯定可选)
                Q.push(t[i]);
            else if(t[i].d == Q.size())///当前商品的天数等于维护的队列,看队头是不是利润更小
                if(t[i].p>Q.top().p)
                    Q.pop(),Q.push(t[i]);
        int ans = 0;
        while(!Q.empty())
            ans+=Q.top().p,Q.pop();
        printf("%d\n",ans);
    }
    return 0;
}
 

上一篇:没有cron的预定PHP脚本执行


下一篇:php – 检查Laravel计划的身份验证