题意:有N种商品,每种商品有价值和保质期。物品在保质期时间内卖出去才会有回报。问怎么卖才能得到最大回报?
4 50 2 10 1 20 2 30 1表示共有四个商品,第一个价值为50保质期为两天,第二个价值为10保质期为一天。。。
思路:贪心 + 并查集。我们肯定优先要卖贵的,所以我们需要按价值排个序。然后尽量在靠后的时间卖,因为这样可以给其他物品更多的时间进行选择。用并查集起一个标记查找作用,f[x]==-1的时候表示这一天可用,否则不可用,东西卖出去了我们就把他的父节点改为前一天。如果根节点为0的话,那么表示该物品应该放弃。
pair默认先按第一个元素从小到大排,第一个相同按第二个从小到大排。
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 10005;
int n, f[MAXN];
pair<int, int> a[MAXN];
int Find(int x)
{
if (f[x] == -1) return x;//可用的时间点
return f[x] = Find(f[x]);
}
int main()
{
while(~scanf("%d", &n))
{
memset(f, -1, sizeof(f));//初始化
for (int i = 0; i < n; i++)
{
scanf("%d%d", &a[i].first, &a[i].second);
}
sort(a, a + n);//按价格从小到大排序
int ans = 0;
for (int i = n - 1; i >= 0; i--)
{
int day = Find(a[i].second);//找到第一个可用的时间点
if (day > 0)//不是第0天
{
f[day] = day - 1;
ans += a[i].first;
}
}
printf("%d\n", ans);
}
return 0;
}
/*
4 50 2 10 1 20 2 30 1
7 20 1 2 1 10 3 100 2 8 2
5 20 50 10
*/