机试算法讲解: 第12题 贪心之我该如何选择:跑男,爸爸去哪儿,好声音,极限挑战

/*
题目:尽可能看多的电视节目,时间为整点
输入:
第一行一个整数n为喜欢看电视的节目总数,下面有n行数据,每一行数据包含2个数据Ti_s,Ti_e表示第i个节目的开始和结束时间
n=0表示输入结束,不做处理
输出:能看到电视节目的个数

输入:
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0

排序:
下标:0    1      2      3       4       5       6       7        8      9       10      11
1 3,	3 4,	0 7,	3 8,	2 9,	5 10,	6 12,	4 14,	10 15,`	8 18,	15 19,	15 20
选择    选择            选择            选择    选择    选择     选择   选择     选择    选择(第一趟),确定1 3,3 4                    j=0
选择    选择                            选择    选择    选择     选择   选择     选择    选择(第二趟)  ,确定1 3, 3 4,5 10               j=1
选择    选择                            选择                     选择            选择    选择(第三趟),确定1 3, 3 4,5 10,10 15         j=5
选择    选择                            选择                     选择            选择        (第四趟),确定1 3, 3 4,5 10,10 15,15 19  j=8
																																		j=10
输出:
5

思路:尽可能选择时间跨度范围小的,并且一个节目的结束时间要小于另一个节目的开始时间。思路错误
应该优先选择结束时间最早的,最优解是结束时间最早。假设第一个节目A[s1,e1],有比A更早结束的节目B,那么用
B替换A不影响A后面节目顺序,因此这也是最优解。
所以当第x-1个节目选择结束后,选择剩余节目中最早结束的节目

贪心算法:
1要证明
2用反证

关键:
1 通过设置标记法,来做过滤,已经过滤掉的,下次循环不做处理
2 设置下一个节目下标时,初始值设为iMinIndex=iNum,以防止最后一次一直拿不到iMinIndex时,程序能够退出循环
3 bool operator < (const Show& show) const//常成员修饰符不能丢,否则报大量stl错误
方法2:
在遍历的过程中,只需搜索一遍,起初设置curTime = 0,然后另curTime<=show[i].endTime,然后不断更新curTime即可
*/

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MaxSize 100


typedef struct Show{
	bool operator < (const Show& show) const//常成员修饰符不能丢,否则报大量stl错误
	{
		return uEndTime < show.uEndTime;
	}
	unsigned uBegTime;
	unsigned uEndTime;
	bool isDel;//删除标记,初始均设为false,一旦确定上一个节目后,下一个节目从剩余节目中选择,如果showA.uEndTime > showB.uBegTime,就设这个节目的isDel=true; 
}Show;

int partition(Show* show,int low,int high)
{
	Show iPos = show[low];
	while(low < high)
	{
		while( low < high && iPos < show[high])
		{
			high--;
		}
		show[low] = show[high];
		while( low < high && show[low] < iPos)
		{
			low++;
		}
		show[high] = show[low];
	}
	show[low] = iPos;
	return low;
}

void quickSort(Show* show,int low,int high)
{
	if(low < high)
	{
		int iPos = partition(show,low,high);
		quickSort(show,low,iPos-1);
		quickSort(show,iPos+1,high);
	}
}

int main()
{
	int iNum;
	Show show[MaxSize];
	while(EOF!=scanf("%d",&iNum) && iNum > 0)
	{
		for(int i = 0;i < iNum ; i++)
		{
			scanf("%d %d",&show[i].uBegTime,&show[i].uEndTime);
			if(show[i].uBegTime < 0 || show[i].uBegTime > 24 || show[i].uEndTime < 0 || show[i].uEndTime > 24)
			{
				printf("The time you input is not valid!\n");
			}
		}
		quickSort(show,0,iNum-1);
		unsigned curTime = 0;
		int iCount = 0;
		for(int j = 0 ; j < iNum ;j++)
		{
			if(curTime <= show[j].uBegTime)
			{
				curTime = show[j].uEndTime;
				iCount++;
			}
		}
		printf("%d\n",iCount);
	}
	system("pause");
	getchar();
	return 0;
}

/*
int main(int argc,char* argv[])
{
	int iNum;
	Show show[100];

	//获取输入
	while(EOF!=scanf("%d",&iNum) && iNum >0 && iNum <= 24)
	{
		//printf("%d\n",iNum);
		for(int i = 0 ; i < iNum ; i++)
		{
			scanf("%d %d",&show[i].uBegTime,&show[i].uEndTime);
			if(show[i].uBegTime < 0 || show[i].uBegTime > 24 || show[i].uEndTime < 0 || show[i].uEndTime > 24)
			{
				printf("The time you input is not valid!\n");
				return -1;
			}
			show[i].isDel = false;
		}

 	    //开始进行贪心算法:2个条件,第i个节目的结束时间一定是最小的,剩下待选节目需要通过 当前节目开始时间 < 上一个节目结束时间,来过滤
    	//先按照节目结束时间早到晚进行快速排序,这样第一个节目的结束时间一定是最早的
		quickSort(show,0,iNum-1);
		int j,k;
		
		int iCount = 0;//能看多少节目的计数器
		for(j = 0; j < iNum ; )
		{
			int iMinIndex = iNum;//设置false的最小下标,易错,若不设置为iNum,永远退出不了循环
			iCount++;//j每次能重新遍历,说明是从当前节目开始的
			bool isFirst = true;//第一次进入的标记
			for(k = j + 1; k < iNum ;k++)
			{
				//易错,之前已经过滤的必须直接过滤掉
				if(true==show[k].isDel)
				{
					continue;
				}
				if(show[j].uEndTime > show[k].uBegTime)
				{
					show[k].isDel = true;
				}
				else
				{
					//确定下一个符合节目最小下标是多少,并且令j从新的节目开始,进行循环
					if(true==isFirst)
					{
						iMinIndex = k;//最后一次为10
						isFirst = false;
					}
				}
			}
			//等到整个循环遍历结束,对j进行重新赋值为iMinIndex,如果最后一次一直没有找到需要特殊处理
			j = iMinIndex;
		}//for
		printf("%d\n",iCount);
	}
	system("pause");
	getchar();
	return 0;
}
*/

你可能感兴趣的:(贪心,机试算法,最优安排)