UVA1316 Supermarket

UVA1316 Supermarket

大意

给一些物品,有过期时间和收益,让你安排卖出的顺序,使得最后的收益最大。

思路

对于每件物品,我们考虑贪心思路,每个物品我们尽量让其在接近过期的时候将其卖掉,这样的话,我们在排序的时候,只需要先按时间从小到大排序,对于时间相同的,我们尽量卖贵的。

我们现在的限制在于每次去找到前面的未用过的天数,来将该物品卖出,于是呢,我们需要维护一个东西,对于第 \(i\) 天,快速找到一个 \(day \le i\),将当前的物品卖掉。

于是我们可以考虑并查集,对于第 \(i\) 天,我们把物品卖掉后,将第 \(i - 1\) 天作为第 \(i\) 天的祖先,这样我们在每次查询的时候就是 \(O(\log n)\) 的时间复杂度。

代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int MAXN = 1e4 + 5;

int T, n, cnt;
int f[MAXN];
int c[MAXN];
struct node{
    int p, d;
}a[MAXN];

bool cmp(node x, node y){
	if(x.p == y.p) return x.d < y.d;
    return x.p > y.p;
}

int fd(int x){
    return f[x] == x ? x : f[x] = fd(f[x]);
}

int main(){
	while(cin >> n){
		for(int i = 1;i <= n;i ++){
			cin >> a[i].p >> a[i].d;
		}
		sort(a + 1, a + n + 1, cmp);
		for(int i = 1;i <= MAXN - 1;i ++) f[i] = i;
		f[0] = 0;
		int ans = 0;
		for(int i = 1;i <= n;i ++){
			int fx = fd(a[i].d);
			if(fx){
				ans += a[i].p;
				int fy = fd(fx - 1);
				f[fx] = fy;
			}
		}
		cout << ans << '\n';
	}
	
    return 0;
}
posted @ 2025-12-16 22:02  To_Carpe_Diem  阅读(5)  评论(0)    收藏  举报