首页 > 其他分享 >POJ 1456 Supermarket (贪心+并查集优化)

POJ 1456 Supermarket (贪心+并查集优化)

时间:2023-02-03 10:37:54浏览次数:34  
标签:selling schedule int 查集 Supermarket 1456 products time include


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 (贪心+并查集优化)_#include

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件商品需要卖,每件商品由(p,t)描述。其中p表示该商品被卖出可获得的利润,t表示该商品被卖出的截止时间。时间从1开始计时,每件商品被卖出的话需要占用1个时间单位。如果某件商品的t=3,那么该商品最多只能在时间1,时间2或时间3 这3个时间点上卖。

        现在的问题是:对于给定的所有商品,我们如何安排每个时间点卖的商品能获得最大利润。输出最大利润即可。

以前用贪心做过两次,这次发现可以使用并查集优化,复杂度起码降低了一半。

  当我们处理第i个商品的时候,我们正常来说应该是从i的截止时间往前找,看看有没有空闲时间点来放商品i。这样查找的过程比较慢。

        这里我们用并查集来做些优化,即对于时间点t来说,如果t时间点空闲,那么fa[t]==-1。 我们用findset(t)查找可行时间点时直接就可以返回t(因为t本来就可行)。如果t时间点不空闲,那么我们令fa[t]==t-1。我们用findset(t)查找可行时间点时返回的(不一定是t-1,如果t-1被占用,返回的就不是t-1。否则返回t-1)是从t-1时间点开始递归查找的结果。

AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<set>
#include<iomanip>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
typedef double ld;
const int INF = 0x3f3f3f3f;
const int MAXN=10000+100;
struct product
{
int v,t;
bool operator < (const product &b)const
{
return v>b.v;//价值越大排名越前
}
} pro[MAXN];
int time[MAXN];//time[i]=x表示在时间点i上放了价值x的商品准备卖
int F[MAXN];
int findset(int i)
{
if(F[i]==-1)return i;
return F[i]=findset(F[i]);
}
int main()
{
int n;
while(scanf("%d",&n)==1)
{
int ans=0;//最大利益
memset(time,0,sizeof(time));
memset(F,-1,sizeof(F));
for(int i=0; i<n; i++)
{
scanf("%d%d",&pro[i].v,&pro[i].t);
}
sort(pro,pro+n);
for(int i=0; i<n; i++)
{
int t = findset(pro[i].t);//找到pro[i].t这个时间往前的第一个空闲时间点
if(t>0)
{
F[t]=t-1;
ans += pro[i].v;
}
}
printf("%d\n",ans);
}
return 0;
}

 

标签:selling,schedule,int,查集,Supermarket,1456,products,time,include
From: https://blog.51cto.com/u_15952369/6035433

相关文章

  • 数据结构——并查集
    一、并查集的概念在计算机科学中,并查集是一种树形的数据结构,用于处理不交集的合并(union)及查询(find)问题。 并查集可用于查询网络中两个节点的状态,这里的网络是......
  • 【新生寒训】day 24 并查集 ST表与RMQ
    【新生寒训】day24并查集ST表与RMQ记得看看这个( ̄▽ ̄)"一些方法论:https://www.cnblogs.com/CTing/p/17067404.html今日小题https://atcoder.jp/contests/abc132/tasks/......
  • POJ--1182 食物链(并查集)
    记录15:392023-1-26http://poj.org/problem?id=1182reference:《挑战程序设计竞赛(第2版)》2.4.4p88Description动物王国中有三类动物A,B,C,这三类动物的食物链构成......
  • 并查集
    简介并查集,是一种树形数据结构,用于维护不相交的集合。基本原理每个集合用一棵树来表示,树根的编号就是整个集合的编号。每个节点存储了它的父节点。实现模板题(AcWing.......
  • 并查集及简单的力扣例题
    优秀讲解视频,五分钟让你理解并查集的核心:youtube.com/watch?v=ayW5B2W9hfo看完感觉并查集其实也很容易,不是特别艰深的概念并查集的构成:group,element,father/representati......
  • 并查集(Disjoint-Set)
    并查集目录并查集定义模板题目原题链接题目描述输入格式输出格式数据范围分析并查集基本原理实现步骤问题1问题2问题3优化代码实现定义并查集(Disjoint-Set)是一种可以......
  • [并查集]People on a Line
    题目描述ThereareNpeoplestandingonthex-axis.LetthecoordinateofPersonibexi.Foreveryi,xiisanintegerbetween0and109 (inclusive).I......
  • C++ 树进阶系列之嘿!别绕了,这个问题可以使用并查集
    1.前言并查集是一种抽象数据结构,可以从名字上解释其功能。集:操作对象是集合群,并查集是与集合操作有关的数据结构。查:查询元素所在的集合。并:合并元素之间关系的集合。......
  • 算法学习笔记(4): 并查集及其优化
    并查集并查集,Disjoint-Set,或者通俗一点,叫做MergeFind-Set,是一种可以动态维护若干个不重叠的集合,并支持集合之间的合并与查询的数据结构。集体来说,并查集支持下列两个操作......
  • 并查集和最小生成树
    并查集初始化\(O(n)\)intfa[N],szp[N],sze[N],loop[N];//fa根节点,szp点的数量,sze边的数量,loop自环的数量intn,m;//n代表点数,m代表边......