poj 1456(贪心、并查集)

Supermarket

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 15416   Accepted: 6941

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. 

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

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 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=10010;
 6 struct node{
 7     int p,d;
 8 }a[maxn];
 9
10 bool cmp(node x,node y)
11 {
12     return x.p>y.p;
13 }
14 bool flag[maxn];
15
16 int main()
17 {
18     int n;
19     while( ~scanf("%d",&n)){
20         memset( a, 0, sizeof a);
21         for(int i=1;i<=n;i++){
22             scanf("%d%d",&a[i].p,&a[i].d);
23         }
24         sort( a+1, a+1+n, cmp);
25 //        for(int i=1;i<=n;i++)
26 //            printf("%d %d\n",a[i].p, a[i].d);
27         memset( flag, 0, sizeof flag);
28         int ans=0;
29         for(int i=1;i<=n;i++){
30             if(!flag[a[i].d]){
31                 flag[a[i].d]=true;
32                 ans+=a[i].p;
33             } else{
34                 for(int j=a[i].d;j>0;j--){
35                     if(!flag[j]){
36                         flag[j]=true;
37                         ans+=a[i].p;
38                         break;
39                     }
40                 }
41             }
42         }
43         printf("%d\n",ans);
44     }
45     return 0;
46 }

用并查集优化

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=10010;
 6 int fa[maxn];
 7 struct node{
 8     int p,d;
 9 }a[maxn];
10
11 bool cmp(node x,node y)
12 {
13     return x.p>y.p;
14 }
15 int find_fa(int x)
16 {
17     return fa[x]==x?x:(fa[x]=find_fa(fa[x]));
18 }
19
20 int main()
21 {
22     int n;
23     while( ~scanf("%d",&n)){
24         for(int i=0;i<maxn;i++)
25             fa[i]=i;
26         for(int i=1;i<=n;i++){
27             scanf("%d%d",&a[i].p,&a[i].d);
28         }
29         sort( a+1, a+1+n, cmp);
30
31         int ans=0;
32         for(int i=1;i<=n;i++){
33             int r=find_fa(a[i].d);
34             if(r>0){
35                 fa[r]=r-1;
36                 ans+=a[i].p;
37             }
38         }
39         printf("%d\n",ans);
40     }
41     return 0;
42 }

原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/9107410.html

时间: 2024-10-12 10:47:36

poj 1456(贪心、并查集)的相关文章

POJ 1456 贪心 并查集

看一下中文版的题目就好,英文题目太晦涩了. 有两种方法可以解题 一种是贪心+优先队列 另一种是贪心+并查集 优先队列  需要说的都在代码注释里 #include<cstdio> #include<queue> #include<algorithm> using namespace std; struct s{ int day, val; }arr[100005]; bool cmp(s a, s b){ if(a.day != b.day) return a.day &

Supermarket poj 1456 贪心+并查集优化

Language: Default Supermarket Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9512   Accepted: 4096 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

POJ 1456 (贪心+并查集) Supermarket

有n件商品,每件商品有它的利润和售出的最后期限,问能够得到的最大利润是多少 这道题和 HDU 1789 Doing Homework again 几乎一模一样,只不过这个是求最的扣分,本题是求最大利润 朴素的做法是: 按照每件商品的利润从大到小排序,有一个busy数组记录那天是否有东西卖出.对于每件商品,从它的截止日期开始遍历,如果那天有东西卖就看看前一天是否有卖东西,直到有一天没有东西卖或者前面的天数都有卖的. 1 //#define LOCAL 2 #include <iostream>

poj 1456 Supermarket - 并查集 - 贪心

题目传送门 传送点I 传送点II 题目大意 有$n$个商品可以销售.每个商品销售会获得一个利润,但也有一个时间限制.每个商品需要1天的时间销售,一天也只能销售一件商品.问最大获利. 考虑将出售每个物品尽量外后安排.这样当一个商品不能安排的时候看能不能替换掉它能够出售的时间中盈利最小的商品. 因此可以将物品排序,这样只用考虑能否让每个物品出售. 为了找到第一个空闲时间,又因为已经安排的时间不会改变,所以用并查集将已经安排了出售的时间段缩起来. Code 1 /** 2 * poj 3 * Prob

poj 1456 Supermarket(并查集维护区间)

 题意:有一些货物,每个货物有价值和卖出的截至日期,每天可以卖一个货物,问能卖出的最大价值是多少. 思路:算法不难想到,按价值降序排列,对于每一件货物,从deadline那天开始考虑,如果哪天空闲那么将货物在该天卖出. 如果直接暴力来做,复杂度为o(n*n),显然不行.可以用并查集来维护当前ddl之前空闲的最近的一天,如果父节点为0说明deadline之前没有空闲的时间,那么该货物就无法卖出. #include<cstdio> #include<cstring> #includ

poj 1456 Supermarket (贪心+并查集)

# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int fa[10010]; struct node { int p; int d; }; struct node a[10010]; bool cmp(node a1,node a2)//利润从大到小 { return a1.p>a2.p; } int find(int x) { if(fa[x]

POJ 2492 (简单并查集) A Bug&#39;s Life

题意:有编号为1~n的虫子,开始假设这种昆虫是异性恋.然后已知xi 和 yi进行交配,根据已知情况分析能否推理出其中是否有同性恋 这道题和 POJ 1182 食物链 十分相似,不过在更新与父节点关系的时候要简单一些 sex数组保存的是与父节点的性别关系,如果与父节点是同性,则为0,否则是1 每次路径压缩的同时要更新sex[a] = (sex[a] + sex[temp]) % 2; 还有就是如果x 和 y 不在一个集合,两棵树进行合并的时候,考虑x px y py 四者之间的关系,有 paren

贪心 + 并查集 之 CODE[VS] 1069 关押罪犯 2010年NOIP全国联赛提高组

/* 贪心 + 并查集 之 CODE[VS] 1069 关押罪犯  2010年NOIP全国联赛提高组 两座监狱,M组罪犯冲突,目标:第一个冲突事件的影响力最小. 依据冲突大小,将M组罪犯按从大到小排序,按照排序结果,依次把每组罪犯分开放入两个监狱, 直到当前这组罪犯已经在同一个监狱中了,此时即为答案. 实现: 1)通过不在同一个监狱的罪犯,推断出在同一个监狱的罪犯.(依据:一共就两个监狱)      ftr[b] = a+n   // a和b是在不同监狱 ftr[c] = a+n   // a和

Codeforces 437D The Child and Zoo(贪心+并查集)

题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去参观动物园,动物园分很多个区,每个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路的权值为该条路连接的两个区中权值较小的一个.如果两个区没有直接连接,那么f值即为从一个区走到另一个区中所经过的路中权值最小的值做为权值.问,平均两个区之间移动的权值为多少. 解题思路:并查集+贪心.将所有的边按照权值排序,从最大的开始连接,每次连接时计算的次数为连接两块的节点数的积(乘法原理). #in

POJ - Colored Sticks - 并查集+字典树

这道题主要还是要判断是不是欧拉图 说白了就是能不能这幅图能不能用一笔画下来,那么就可以知道了,如果是一个环状的,说明奇数度就不存在,否则就只能用两个奇数度(起点终点)//我的理解这是 只需要用字典树将单词变为对应的一个数字,然后并查集操作就可以,需要维护一个度变量 #include<stdio.h> #include<string.h> int du[500010],p[500010]; int tot=1; struct tree { tree *next[30]; int id