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;
}


 

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