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.
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
题目大意 是每个商品有一个最迟销售时间(可以在这个时间之前销售完),和一个销售该商品获得的利润。现在给出n个商品的最迟销售时间和利润,求一个获得利润最大的销售计划。(问先卖什么后卖什么,使获得的利润最大)
这是一道贪心算法题,刚开始我贪错了,想着先选一个截止时间最长且利益最大的来卖(这样保证能卖的东西最多),然后依次降低截止时间选择在这个时间最长利益最大的加入销售计划,一排便发现选择的过程比较复杂,思考来思考去最后还是没想出好的实现方式。而这道题实际上跟另外一道贪心算法题一样:HDU 1074 doing homework.
先给利润排个序,从利润最大的开始卖,每一个商品都在他的截止日期那天卖出,依次遍历过去,如果当天无法卖出,就往前推,直到推到可以卖出或完全卖不出去。
贴出两个代码,一个用优先队列实现,一个用sort排序实现(其实我是想看一下哪个更快):
优先级队列:
这个缩进我也不知道怎么回事,贴下来就这样了。
/*优先级队列*/
#include<iostream>
using namespace std;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
struct Node
{
int p,d;
bool operator < (const Node &r) const{
return r.p>p;
}
};
int hash1[10010];
Node g[10010];
int n;
priority_queue <Node> p;
int main(){
int sum=0;
while(scanf("%d",&n)!=EOF){
while(!p.empty()) p.pop();
sum=0;
memset(hash1,0,sizeof(hash1));
for(int i = 1;i <= n;i++ ){
scanf("%d%d",&g[i].p,&g[i].d);
p.push(g[i]);
}
Node top;
int ded;
while(!p.empty()){
top=p.top();
ded=top.d;
p.pop();
while(ded>0){
if(!hash1[ded]){
sum+=top.p;
hash1[ded]=1;
break;
}
else
ded--;
}
}
printf("%d\n",sum);
}
}
sort排序:
#include<iostream>
using namespace std;
#include<stdio.h>
#include<string.h>
#include<algorithm>
struct Node
{
int p,d;
};
int hash1[10010];
Node g[10010];
int n;
bool cmp(Node a,Node b){
return a.p>b.p;
}
int main(){
int sum=0;
while(scanf("%d",&n)!=EOF){
sum=0;
memset(hash1,0,sizeof(hash1));
for(int i = 1;i <= n;i++ )
scanf("%d%d",&g[i].p,&g[i].d);
sort(g+1,g+n+1,cmp);
for(int i = 1;i <= n; i++){
int ded=g[i].d;
while(ded>0){
if(!hash1[ded]){
sum+=g[i].p;
hash1[ded]=1;
break;
}
else
ded--;
}
}
printf("%d\n",sum);
}
}
其实这道题是我们并查集的一道练习专题,但是我并没有用并查集去做。就这么水过去了。