1316 - Supermarket
Time limit: 3.000 seconds
A supermarket has a set Prod of products on sale. It earns a profit px foreach product x in Prod sold by a deadline dx that is measured as an integralnumber of time units starting from the moment the sale begins. Each producttakes precisely one unit of time for being sold. A selling schedule is anordered subset of products Sell from Prod such that the selling of each productx in Sell, according to the ordering of Sell, completes before the deadline dxor just when dx expires. The profit of the selling schedule is. An optimal selling schedule is a schedule with amaximum profit.
For example, consider the products Prod={a,b,c,d} with (pa,pa=(50,2),(pb,pb=(10,1), (pc,pc=(20,2), and (pd,pd=(30,1). The possible sellingschedules 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 ofthese products is sold by its deadline. Sell is the optimal schedule andits profit is 80.
Write a program that reads sets of products from an input text file andcomputes the profit of an optimal selling schedule for each set ofproducts.
Input
A set of products starts with an integer 0 <= n <= 10000, which is the number ofproducts 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 sellingdeadline of the i-th product. White spaces can occur freely in input. Inputdata terminate with an end of file and are guaranteed correct.
Output
For each set of products, the program prints on the standard output theprofit of an optimal selling schedule for the set. Each result is printedfrom 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
The sample input contains two product sets. The first set encodes theproducts from table 1. The second set is for 7 products. The profit of anoptimal schedule for these products is 185.
解题报告:经典贪心。贪心策略很容易想,也有很多种。
我想到的是这样的:截止时间排序。然后按照时间从大到小遍历,将改时间前要完成的任务加入优先队列,每次选择价值最大的那个任务完成。因为当前的任务的时间都是满足条件的,这样到了初始时间,得到的结果必然最优。
唯一要注意的问题是,不要用~scanf("%d", &n)的写法,会TLE……我一直用到现在没挂过题,今天终于发现这种写法也是有问题的。用scanf("%d", &n) == 1就好了。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int n;
while(scanf("%d", &n) == 1)
{
vector<int> vec[11111];
int p, d;
for(int i=0;i<n;i++)
scanf("%d%d", &p, &d), vec[d].push_back(p);
int ans = 0;
priority_queue<int> que;
for(int t=10000;t>=1;t--)
{
for(int j=0;j<vec[t].size();j++)
que.push(vec[t][j]);
if(que.size() == 0) continue;
ans += que.top();
que.pop();
}
printf("%d\n", ans);
}
}