51nod 1163 最高的奖励 【贪心 ,并查集】

  


并查集做法:

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 50005
long long  f[N];
pair <long long  ,long long  > m[N];  //作为结构体的作用    第一个为first  第二个为 second   按frist排序  小到大 

int find(int x){
	if(x<=0) return -1; //这是边界 如果在最迟时间前都没有时间做这件事 就不再执行这个任务
	
	if(x==f[x]) return f[x]=x-1; //并查集 实现 一个状态的(存进去就有) 位置的存放  
	else return find(f[x]); //如果没有找到 该点所放的位置 就接着找前面的位置 
} 
int main(){
	long long  n,sum=0;
	cin>>n;
	for(int i=0;i<n;i++){
		f[i]=i;
		cin>>m[i].second>>m[i].first;
		m[i].first=-m[i].first;  // 将值反过来  就变成了 从大到小的排序了  巧妙  不用定义bool判断排序了 
		if(m[i].second>n) m[i].second=n; //只能从n开始向下找 
	}
	sort(m,m+n);//排序一下
	f[n]=n;
	 
	for(int i=0;i<n;i++){
		if(find(m[i].second)>=0) //就存入该店的最大值
			sum-= m[i].first;
	}
	cout<<sum<<endl;
	return 0;
}
		
		



贪心做法
#include<iostream>
#include<algorithm>
using namespace std;
struct act{
	long long  x,y;
}a[50005];
bool book[50005];
bool cmp(act a,act b){
	if(a.y==b.y) return a.x<b.x; //奖励相等按时间小的排 
	return a.y>b.y;
}
int main(){
	int n;
	long long ans=0;
	cin>>n;
	for(int i=0;i<n;i++)	cin>>a[i].x>>a[i].y;
	sort(a,a+n,cmp);
	//for(int i=0;i<n;i++)	cout<<a[i].x<<" "<<a[i].y<<endl;   //输出  
	for(int i=0;i<n;i++){ //在奖励优先的情况下  放任务 
		int k=a[i].x;
		while(k){//  意思就是在k之前的几个时间里放任务  
			if(!book[k]){   //是否放了任务  如果没有放任务 就在时间点放下任务 
				book[k]=1;  //放过 
				ans+=a[i].y; //奖励的累计 
				break; //该奖励已经找到地方放了 
			}
			else k--;  //该点没有找到 就放之前的地方 
		} //对k之前的时间段放任务  
	}
	cout<<ans<<endl;
	return 0;
}
/*
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
*/


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