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
*/


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