题目链接:https://ac.nowcoder.com/acm/problem/50995
题目大意:
思路:贪心+优先队列:我们按时间从小到大排序,当前时间T。并且维护已经选取的商品的最小利润。如果当前商品的时间==T。那么从优先队列来里面找到最小值如果<当前商品的利润:替换。
如果当前商品的时间<T,直接选取。
思路:并查集:我们按商品的利润从大到小排序,那么我们希望从前往后贪心。并且把每个商品放在自己过期时间前越后越好。我们用并查集来维护时间。f[i]=-1:第i天空闲。否则f[x]=y。x前面第一个空闲的天数是f[y]。
如果找到空闲天x.维护f[x]=f[x-1]
1:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
struct node{
int w, t;
}a[10005];
priority_queue<LL, vector<LL>, greater<LL> > q;
int main(){
int n;
while(~scanf("%d", &n)){
for(int i=1; i<=n; i++){
scanf("%d%d", &a[i].w, &a[i].t);
}
sort(a+1, a+1+n, [](node &a, node &b){return a.t<b.t;});
LL T=0, ans=0;
for(int i=1; i<=n; i++){
if(T<a[i].t){
q.push(a[i].w);
T++;
ans+=a[i].w;
}
else if(a[i].w>q.top()){
ans+=(a[i].w-q.top());
q.pop(); q.push(a[i].w);
}
}
printf("%lld\n", ans);
while(!q.empty()){
q.pop();
}
}
return 0;
}
*****************************
2:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
struct node{
int w, t;
}a[10005];
int f[10005];
int fd(int x){
if(f[x]==-1) return x;
return f[x]=fd(f[x]);
}
int main(){
int n;
while(~scanf("%d", &n)){
memset(f, -1, sizeof(f));
for(int i=1; i<=n; i++){
scanf("%d%d", &a[i].w, &a[i].t);
}
sort(a+1, a+1+n, [](node &a, node &b){return a.w>b.w;});
LL ans=0;
for(int i=1; i<=n; i++){
int pos=fd(a[i].t);
if(pos>0){
ans+=a[i].w;
f[pos]=pos-1;
}
}
printf("%lld\n", ans);
}
return 0;
}
京公网安备 11010502036488号