【算法竞赛进阶指南】Supermarket 贪心+并查集
题意
有一个超市一天只能卖一件商品,现在共有 n 件商品,给出每件商品的价格以及过期时间。
求出最大利润。
思路
按照商品的价值从高到低排序,如果价值相同按照过期时间从高到底排序。
依次遍历每件商品,第 i 件商品,应该离它的过期时间越近,卖出去才好。
那么我们用并查集维护过期时间为 \(t\) 的物品能放的最大的位置 \(pos\ (pos\leq t)\) 。
代码
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <vector>
#define pb push_back
#define pii pair<int, int>
#define pll pair<int, int>
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
using namespace std;
struct node {
int val, id;
} arr[N];
bool cmp(node a, node b)
{
if (a.val == b.val)
return a.id > b.id;
return a.val > b.val;
}
int fa[N];
int find(int x)
{
if (fa[x] == x)
return fa[x];
return fa[x] = find(fa[x]);
}
int val[N];
int main()
{
int n;
while (~scanf("%d", &n)) {
memset(val, 0, sizeof(val));
for (int i = 1; i <= n; i++) {
scanf("%d%d", &arr[i].val, &arr[i].id);
}
for (int i = 1; i <= 10000; i++) {
fa[i] = i;
}
sort(arr + 1, arr + 1 + n, cmp);
for (int i = 1; i <= n; i++) {
int pos = find(arr[i].id);
val[pos] = arr[i].val;
if (pos)
fa[pos] = pos - 1;
}
int sum = 0;
for (int i = 1; i <= 10000; i++) {
sum += val[i];
}
printf("%d\n", sum);
}
return 0;
}