pku1456贪心+并查集/线段树

来源:互联网 发布:跑马拉松的装备淘宝店 编辑:程序博客网 时间:2024/05/16 12:28

 

题意:给出10000个任务,每个任务告诉你收益pi和截止日期di,然后求最大收益。。。

 

分析:以前做过的,突然发现忘了当时并查集怎么做的。。。水啊。。。

其实就是贪心,按照收益从大到小排序,然后每次选最大的那个去填可以填的最大的一个时间。。。这个时间可以用并查集来维护,最开始每天都指向自己,当某一天被用之后就指向前一天,(或者可以直接指向前一天指向的那一天---没必要)。。。当然find为0的无视掉就好了。。。。

 

其实这个很显然也可以用线段树维护这个最大值,但时间慢太多了。。。

 

 

并查集代码:

#include<iostream>#include<algorithm>using namespace std;const int N=10010;int n, m, sum, f[N];struct node{int p, d;} a[N];int cmp(const node &a, const node &b){return a.p > b.p;}int findf(int x){if(f[x]!=x)f[x] = findf(f[x]);return f[x];}void unionf(int x, int y){int fx = findf(x);int fy = findf(y);if(fx!=fy){f[fx] = fy;}}int main(){int i, j, k, x, y, tmp, mx;while(scanf("%d", &m)!=EOF){mx = 0;for(i=0; i<m; i++){scanf("%d%d", &a[i].p, &a[i].d);if(mx<a[i].d)mx = a[i].d;}for(i=0; i<=mx; i++){f[i] = i;}sort(a, a+m, cmp);sum = 0;for(i=0; i<m; i++){tmp = findf(a[i].d);if(tmp>0){sum += a[i].p;unionf(tmp, tmp-1);}}printf("%d\n", sum);}return 0;}


 

原创粉丝点击