【算法竞赛进阶指南】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;
}
posted @ 2020-11-07 17:39  Valk3  阅读(102)  评论(0编辑  收藏  举报