AcWing 145. 超市(优先队列 / 并查集)

2024-04-16 01:38

本文主要是介绍AcWing 145. 超市(优先队列 / 并查集),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

超市里有N件商品,每个商品都有利润pi和过期时间di,每天只能卖一件商品,过期商品(即当天di<=0)不能再卖。

求合理安排每天卖的商品的情况下,可以得到的最大收益是多少。

输入格式
输入包含多组测试用例。

每组测试用例,以输入整数N开始,接下里输入N对pi和di,分别代表第i件商品的利润和过期时间。

在输入中,数据之间可以自由穿插任意个空格或空行,输入至文件结尾时终止输入,保证数据正确。

输出格式
对于每组产品,输出一个该组的最大收益值。

每个结果占一行。

数据范围
0≤N≤10000,
1≤pi,di≤10000
输入样例:
4 50 2 10 1 20 2 30 1

7 20 1 2 1 10 3 100 2 8 2
5 20 50 10
输出样例:
80
185

用优先队列或者并查集,本质上是在相同天数的情况下,尽可能放大卖利润大的商品。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;const int maxn = 1e5 + 7;struct Node
{int p,d;bool operator < (const Node&rhs)const{return d < rhs.d;}
}a[maxn];priority_queue<int,vector<int>,greater<int> >Q;int main()
{int n;while(~scanf("%d",&n)){for(int i = 1;i <= n;i++){scanf("%d%d",&a[i].p,&a[i].d);}sort(a + 1,a + 1 + n);for(int i = 1;i <= n;i++){if(a[i].d > Q.size()){Q.push(a[i].p);}else if(a[i].d == Q.size() && a[i].p > Q.top()){Q.pop();Q.push(a[i].p);}}int ans = 0;while(!Q.empty()){ans += Q.top();Q.pop();}printf("%d\n",ans);}return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;const int maxn = 1e5 + 7;int fa[maxn];struct Node
{int p,d;bool operator < (const Node&rhs)const{return p > rhs.p;}
}a[maxn];priority_queue<Node>Q;int findset(int x)
{if(fa[x] == x)return x;return fa[x] = findset(fa[x]);
}void Union(int x,int y)
{int fx = findset(x),fy = findset(y);if(fx != fy) fa[fx] = fy;
}int main()
{int n;while(~scanf("%d",&n)){int cnt = 0;int mx = 0;for(int i = 1;i <= n;i++){scanf("%d %d",&a[i].p,&a[i].d);mx = max(mx,a[i].d);}sort(a + 1,a + 1 + n);for(int i = 1;i <= mx;i++)fa[i] = i;int ans = 0;for(int i = 1;i <= n;i++){int now = findset(a[i].d);if(now > 0){
//                Union(now,now - 1);fa[now] = now - 1;ans += a[i].p;}}printf("%d\n",ans);}return 0;
}

这篇关于AcWing 145. 超市(优先队列 / 并查集)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907490

相关文章

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 1182 并查集 食物链类

题意: 有n只动物,分别编号1....n。所有动物都属于A,B,C中的一种,已知A吃B,B吃C,C吃A。 按顺序给出下面两种共K条信息: 1. x 和 y 属于同一类。 2. x 吃 y 。 然而这些信息可能会出错,有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的 x 和 y 不在n的范围内。 求k条信息中有多少条是不正确的。 解析: 对于每只动物,创建3个元素 i

poj 2431 poj 3253 优先队列的运用

poj 2431: 题意: 一条路起点为0, 终点为l。 卡车初始时在0点,并且有p升油,假设油箱无限大。 给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。 问最少加几次油可以到达终点,若不能到达,输出-1。 解析: 《挑战程序设计竞赛》: “在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

POJ2010 贪心优先队列

c头牛,需要选n头(奇数);学校总共有f的资金, 每头牛分数score和学费cost,问合法招生方案中,中间分数(即排名第(n+1)/2)最高的是多少。 n头牛按照先score后cost从小到大排序; 枚举中间score的牛,  预处理左边与右边的最小花费和。 预处理直接优先队列贪心 public class Main {public static voi

POJ1988带权并查集

M u v 将u所在的堆移动到v所在的堆的上面 C u 求u的下面有多少块 带权并查集 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;i

POJ1703带权并查集

D: u v  u与v在不同的集合 A: u v  查询u与v的关系 1)压缩路径过程        fu->root   0  1  u-fu 0                 0  1   1                 1  0 2)合并过程 fu->fv      u->fu   0 1   v->fv 0            1 0 1            0

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访