北大ACM——Cleaning Shifts(贪心)

本题属于区间覆盖问题——贪心经典问题之一。
原题可转化为有一个线段[s,t],选择最少的区间将这条线段完全覆盖。不过!!!本题有一个不太一样的就是,上一头牛从t时刻结束,下一头牛可以从t+1时刻开始工作。
贪心策略:
1.先将数据按开始时间a[i]从小到大排序。(a[i]相同可以按b[i]从大到小排序,也可以不用,反正不会影响最终结果)
2.一开始,以s为有效起点,选取结束时间b[i]最长的区间,选完后,有效起点更改为b[i]+1。
3.重复2,知道结束时间>=t。

伪代码:
输入N,T;
输入s[N],t[N];
int flag1=0,flag2=0,sum=1;
long long right,left;
if(s[]中有起点<=1的) flag1=1;
if(t[]中有结束时间>=T的) flag2=1;
if(flag1&&flag2)
{
排序;
right=left=1;
while(i<N&&left<T)
{
if(s[i]小于或等于有效起点right,而且t[i]大于left)left=t[i];
else if(选完了最长区间)
{
if(区间之间“断层”)
{ right=left+1;sum++;left改变}
else break;
}
}
if(left>=T) 输出sum;
else 输出-1
}else 输出-1

代码如下:

#include<cstdio>
#include<cmath>
using namespace std;
long long s[25005],t[25005];
void qsort(int x,int y) //数据较大,应使用快排
{
	if(y-x>1)  //莫忘
	{
		int i=x,j=y-1;
		long long X=s[x],Y=t[x];
		while(i<j)
		{
			while(i<j&&s[j]>=X)
			    j--;
			if(i<j)
			{
				s[i]=s[j];
				t[i++]=t[j];
			}
			while(i<j&&s[i]<X)
			    i++;
			if(i<j)
			{
				s[j]=s[i];
				t[j--]=t[i];
			}
		}s[i]=X;t[i]=Y;
		qsort(x,i);
		qsort(i+1,y);
	}
}
int main()
{
	int N,T;	//while(1){
	int i,flag1=0,flag2=0,sum=1;
	long long right,left; //right表有效起点,left表目前覆盖的时间(这里左右弄反了,实际上right和left的作用应反过来,不过也没事啦)
	scanf("%d %d",&N,&T);
	for(i=0;i<=N-1;i++)
	{
		scanf("%lld %lld",&s[i],&t[i]);
		if(s[i]<=1) flag1=1;   //s[]中有有效起点为最开始的 1 的
		if(t[i]>=T) flag2=1; //t[]中有最终结束时间为 T 的
	}
	if(flag1&&flag2)
	{
		qsort(0,N);
	//	for(i=0;i<=N-1;i++) printf("%d %d\n",s[i],t[i]);
	    right=left=1;
	    i=0;
	    while(i<N&&left<T)  //用while简洁,注意循坏结束条件的控制
	    {
	    	if(s[i]<=right&&t[i]>left)  //选取有效起点为right的最长区间
	    	    left=t[i];
	    	else if(s[i]>right)  //**“选完了”的标志是:s[i]大于有效起点**
	    	{
	    		if(s[i]<=left+1) //**“不断层”的标志是:s[i]小于或等于left+1**
	    		{
	    			right=left+1;sum++; //更改有效起点
	        		if(t[i]>left) left=t[i]; //如果这时候t[i]大于left,将它的值赋给left
				}
				else break; //“断层”就可以不用继续了
			}
			i++;
		}
		if(left>=T) printf("%d\n",sum);
		else printf("-1\n");
	}
	else printf("-1\n");//}
	return 0;
}

代码中要注意两点:
1.选完了的标志;
2.“断层”的标志。

很经典的贪心,要掌握好,紫书中有讲解,要掌握理解好。

猜你喜欢

转载自blog.csdn.net/shamansi99/article/details/87022369
今日推荐