【luoguUVA1316】 Supermarket--普通并查集+贪心
题目描述
有一个商店有许多批货,每一批货又有N(0<=N<=10^4 )个商品,同时每一样商品都有收益P_iPi ,和过期时间D_iDi (1<=Pi,,Di <=10^4 ),一旦超过了过期时间,商品就不能再卖。
你要做的就是求出每批货最多能得到多少收益。
输入输出格式
输入格式
多组数据,每组先给出一个整数N,表示这批货的商品个数。
然后有N对数,每对数有两个用空格隔开的正整数P_i,D_i ,表示第i个商品的收益和过期时间。相邻两对数之间用空格隔开。
输入以一个文件终止符结束,并且保证所有输入数据正确。
输出格式
对于每组数据,输出一行一个整数表示该批货物能卖出的最大价格。
感谢@Rye_Catcher 提供的翻译
题目描述
输入格式
无
输出格式
无
输入输出样例
输入 #1
4 50 2 10 1 20 2 30 1 7 20 1 2 1 10 3 100 2 8 2 5 20 50 10
输出 #1
80 185
思路:这道题是一个贪心,我们可以维护一个大根堆,按价值排序
之后,已过期当天为期限,每次从大往小扫,如果该地方(过期当天)
已经有值,则往前推,并查集可维护前面可以占用的时间》
代码:
#include<cstdio> #include<iostream> #include<cstdlib> #include<queue> #include<cstring> using namespace std; int n,cnt,sum; bool lim[100000]; struct node{ int val,t; friend bool operator < (const node &a,const node &b) { return a.val < b.val; } }e[100000]; priority_queue <node> q; int main() { while(scanf("%d",&n)!=EOF) { memset(e,0,sizeof(e)); memset(lim,0,sizeof(lim)); sum=0; for(int i=1;i<=n;i++) { scanf("%d%d",&e[i].val,&e[i].t); q.push( (node) {e[i].val,e[i].t} ); } // for(int i=1;i<=n;i++) // { // node p=q.top(); // q.pop(); // int aa=p.val; // cout<<aa<<" "; // } // cout<<endl; for(int i=1;i<=n;i++) { node a=q.top(); q.pop(); int x=a.t; if(lim[x]) { while(lim[x])x--; } if(x>0)sum+=a.val,lim[x]=1; } printf("%d\n",sum); } return 0; }