pku1456贪心+并查集/线段树

 

题意:给出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;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章