天天看點

貪心模闆題

源自acwing上的模闆題

1、區間選點 && 2、最大不相交區間的數量

#include <iostream>
#include <algorithm>

using namespace std;

const int N=1e5+10;

struct node 
{
	int l,r;
}range[N];

bool cmp(node a,node b)
{
	return a.r<b.r;
}

int main()
{
//	freopen("input.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	int n;
	cin>>n;
	for(int i=0;i<n;i++) 
	{
		cin>>range[i].l>>range[i].r;		
	}
	sort(range,range+n,cmp);
	int res=0,right=-2e9;
	for(int i=0;i<n;i++)
		if(range[i].l>right)
		{
			res++;
			right=range[i].r;
		}
	cout<<res;
	
	return 0;
 } 
           

3、區間分組

#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

const int N=1e5+10;

struct node
{
	int l,r;
}range[N];

bool cmp(node a,node b)//對左端點進行排序
{
	return a.l<b.l;
 } 

int main()
{
//	freopen("input.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>range[i].l>>range[i].r;
	sort(range,range+n,cmp);
	priority_queue<int,vector<int>,greater<int> > head;
	for(int i=0;i<n;i++)
	{
		if(head.empty()||head.top()>=range[i].l) head.push(range[i].r);//右端點最小的小組如果大于等于此區間右端點 
		else 
		{
			head.pop();
			head.push(range[i].r);
		}
	 } 
	 cout<<head.size();
	
	return 0;
 } 
           

4、區間覆寫

#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

const int N=1e5+10;

struct node
{
	int l,r;
}range[N];

bool cmp(node a,node b)
{
	return a.l<b.l;
}

int main()
{
//	freopen("input.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	int st,ed,n;
	cin>>st>>ed>>n;
	for(int i=0;i<n;i++)
	{
		cin>>range[i].l>>range[i].r;
	}
	sort(range,range+n,cmp);
	int res=0;
	for(int i=0;i<n;i++)
	{
		int j=i,r=-2e9;
		while(j<n&&range[j].l<=st)
		{
			r=max(r,range[j].r);
			j++;
		}
		if(r<st) 
		{
			res=-1;
			break;
		}
		res++;
		if(r>=ed) break;
		i=j-1;//需要更新i的值來重新周遊 
		st=r;//每次選擇完一個區間之後更新st起始點的值 
	}
	cout<<res;
	
	return 0;
 }