题意:有一些货物,每个货物有价值和卖出的截至日期,每天可以卖一个货物,问能卖出的最大价值是多少。
思路:算法不难想到,按价值降序排列,对于每一件货物,从deadline那天开始考虑,如果哪天空闲那么将货物在该天卖出。
如果直接暴力来做,复杂度为o(n*n),显然不行。可以用并查集来维护当前ddl之前空闲的最近的一天,如果父节点为0说明deadline之前没有空闲的时间,那么该货物就无法卖出。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std;
const int maxn = 10000 + 100;
const int INF = 0x3f3f3f3f;
int pre[maxn];
int n;
struct Prod {
int val, ddl;
bool operator < (const Prod& A) const { return val > A.val;}
} prod[maxn];
int find(int x) {
if(x == pre[x]) return x;
return pre[x] = find(pre[x]);
}
void init() {
for(int i = 1; i < 10005; i++) pre[i] = i;
for(int i = 0; i < n; i++) cin >> prod[i].val >> prod[i].ddl;
}
void solve() {
int ans = 0;
sort(prod, prod+n);
for(int i = 0; i < n; i++) {
if(find(prod[i].ddl)) {
ans += prod[i].val;
pre[pre[prod[i].ddl]] = find(pre[prod[i].ddl]-1);
}
}
cout << ans << endl;
}
int main() {
//freopen("input.txt", "r", stdin);
while(scanf("%d", &n) == 1) {
init();
solve();
}
return 0;
}