Supermarket超市(贪心算法 优先队列)- POJ 1456

Posted ACM算法日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Supermarket超市(贪心算法 优先队列)- POJ 1456相关的知识,希望对你有一定的参考价值。

TianMaXingKong童鞋的解题报告,好萌的~超厉害哦)

Supermarket超市(贪心算法 优先队列)- POJ 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. 


Supermarket超市(贪心算法 优先队列)- POJ 1456

POJ 个学习英语的好地方,哈哈哈=( ̄︶ ̄)=


参考翻译(水平有限,欢迎批评)


一家超市有一套商品Prod待售。它每个商品 x∈Prod 的盈利为  px ,期限 dx 是从销售开始就被计算的一个整数时间单位。每件商品需要精确地占用一个单位的时间以被销售。一个销售时间表是商品 Sell ≤ Prod 的一个有序子集,以便于每件商品  x∈Prod 

的销售根据 Sell 排序,需在期限dx之前或者就在dx到期时完成。销售时间表的好处是 Profit(Sell)=Σx∈Sellpx。一个最优的销售时间表是个可以利润最大化的时间表。

举个例Prod={a,b,c,d},   (pa,da)=(50,2) ,  (pb,db)=(10,1) ,  (pc,dc)=(20,2) ,  (pd,dd)=(30,1) .可能的销售时间表被罗列在表1。例如,时间表Sell = {da}表示商品 的 销售从时间0开始,到时间1结束,而商品 的销售从时间1开始,到时间2结束。这些商品的每一件都在截止前销售。Sell 是最优时间表,且利润为80


Supermarket超市(贪心算法 优先队列)- POJ 1456


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.


一组产品以0 <= n <= 10000的整数开始,该整数是该组中的产品的数量,并且继续n组整数pi di1 <= pi <= 100001 <= di <= 10000,表示第i种产品的利润和销售期限。输入空白可以自由发生。输入数据以文件结尾终止并保证正确。


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.


样本输入包含两个产品组。第一组编码表1中的产品。第二组编码7个产品。这些产品的最佳时间表的利润是185


分析:

      题目大意是: 超市有堆商品要卖,但是它们有不同的利润和期限,得在此期限前卖出去,不一定要全部卖出,但是要求利润可以最大化。这些商品是从同一天开始一起贩卖的,每天只能卖一种商品。

Supermarket超市(贪心算法 优先队列)- POJ 1456

比如这堆商品分为a,b,c,d四种 

(pa,da)=(50,2) ,  (pb,db)=(10,1) ,  (pc,dc)=(20,2) ,  (pd,dd)=(30,1) 


Supermarket超市(贪心算法 优先队列)- POJ 1456

总共卖的天数=商品中期限最长的时间,所以为2

0-11d=30(要把a留到第二天卖,所以只有三种可以选,同选利润最大的)

0-22a=50(只有ac可以卖,选择利润最大的)

这是典型的贪心算法问题(活动安排+优先队列

        输入不定测试组,以文件结尾结束,每组先输入一个n,然后是输入npi  di  ,表示第 个商品的利润和 deadline 

        1. 按照 dx    px 从大到小排序

        2. 建立优先队列 big

        3. 从截止日期开始一天一天往前找截止日期内的,且还没有被卖过的,利润最大的商品

        4. big push() day 到 最大截止日期的所有商品的利润值

        5. 注意不要重复压入

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

排序后:

5 20    

50 10

10 3

100 2

8 2

20 1

2 1

20天时选择最大利润商品,即x[0].dx ,第11-19天,无商品可卖。。。第10天选50,第三天选10。。。

最后结果为:20+10+10+50+5=85

AC代码

#include<iostream>
#include<queue>
#include<algorithm>
#define maxn 100001
using namespace std;
int out[maxn], longth = 0;
class X
{

public:
   int px;
   int dx;
};
bool sort_dx_px(const X &x1, const X &x2)
{
   if (x1.dx > x2.dx)  return true;
   else    if (x1.dx == x2.dx)
   {
       if (x1.px > x2.px)
           return true;
       else
           return false;
   }
   else
       return false;

}
int main()
{
   int n = 0;
   while (scanf("%d", &n) != EOF)
   {
       X *x = new X[n];                //动态构建,节约空间
       int maxx = 0;                   //当前数据组的最大利润
       if (n == 0)
       {
           out[longth++] = 0;
           continue;
       }
       for (int i = 0; i < n; i++)
           cin >> x[i].px >> x[i].dx;
       sort(x, x + n, sort_dx_px);     // 按照 dx 和 px 从小到大排列
       priority_queue<int> big;        //优先队列
       //从截止日期 一天一天 往前找 期限内的利润最大的商品
       int i = 0;
       for (int day = x[0].dx; day > 0; day--)
       {
           for (; i < n && day <= x[i].dx; i++)
           {
               if (day > x[i - 1].dx)  break;
               big.push(x[i].px);
           }
           while (!big.empty())
           {
               maxx += big.top();
               big.pop(); break;
           }
       }
       out[longth++] = maxx;
       delete[] x;     //消除内存空间
   }
   for (int i = 0; i < longth; i++)
   {
       cout << out[i] << endl;
   }
   return 0;
}


以上是关于Supermarket超市(贪心算法 优先队列)- POJ 1456的主要内容,如果未能解决你的问题,请参考以下文章

supermarket [POJ1456]

POJ-1456 Supermarket贪心+并查集

区间贪心算法 结合优先队列使用效果更佳——以POJ 237613283190为例

poj 1456 supermarket

#POJ1456_Supermarket

supermarket是啥意思?