前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Supermarket超市(贪心算法 优先队列)- POJ 1456

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

作者头像
ACM算法日常
发布2018-08-07 18:14:28
7080
发布2018-08-07 18:14:28
举报
文章被收录于专栏:ACM算法日常ACM算法日常

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

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 一个学习英语的好地方,哈哈哈=( ̄︶ ̄)=

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

一家超市有一套商品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 = {d,a}表示商品 d 的 销售从时间0开始,到时间1结束,而商品 a 的销售从时间1开始,到时间2结束。这些商品的每一件都在截止前销售。Sell 是最优时间表,且利润为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.

一组产品以0 <= n <= 10000的整数开始,该整数是该组中的产品的数量,并且继续n组整数pi di,1 <= pi <= 10000和1 <= 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

代码语言:javascript
复制
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

代码语言:javascript
复制
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。

分析:

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

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

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

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

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

0-2第2天a=50(只有a和c可以卖,选择利润最大的)

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

输入不定测试组,以文件结尾结束,每组先输入一个n,然后是输入n组 pi di ,表示第 i 个商品的利润和 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代码:

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档