线段树可以搞搞,按端点排个序,然后每次找端点以内最大的,然后删除。
学了下并查集的搞法。先按价值贪心,每次拿走一个价值的时候,将这个价值所在集合的日期,推前一天,表示接下来日期在这段数内的物品只能在这段时间之前取,这个物品能取得日期为0的时候代表没法取了。
#pragma comment(linker,"/STACK:102400000,102400000") #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<iostream> #include<string> #include<queue> #include<stack> #include<list> #include<stdlib.h> #include<algorithm> #include<vector> #include<map> #include<cstring> #include<set> using namespace std; typedef long long LL; const int maxn = 11111; int father[maxn]; int getfather(int x) { if (x != father[x]) father[x] = getfather(father[x]); return father[x]; } struct Node { int a; int b; }node[maxn]; int cmp(const Node &a, const Node &b) { return a.a > b.a; } int main() { int n; while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; i++) scanf("%d%d", &node[i].a, &node[i].b); sort(node, node + n, cmp); int ans = 0; for (int i = 1; i < 11111; i++) father[i] = i; for (int i = 0; i < n; i++) { int fa = getfather(node[i].b); if (fa > 0) { ans += node[i].a; father[fa] = fa - 1; } } cout << ans << endl; } return 0; }