TOJ 2882


题目连接:

http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=2882


题目类型:

贪心算法


数据结构:

struct GREEDY
{
	int s;
	int f;
};


思路分析:

--------------------------------------------------------------------------------------------

贪心思路
最优活动安排问题
根据结束时间排列升序排列
只要令后一个活动的结束时间不小于前一个活动的结束时间即可定下安排
(如果某个活动的结束时间=起始时间,则这个活动的用时为0,其可以安排在任何该时间结束的活动之后,不能之前)


证明:

看贪心思想的部分最优解能否得出整体最优解
每个活动按结束时间升序排序,每个活动的安排范围是该活动的结束时间到前一个活动的结束时间.
以第一个活动为第一部的最优子问题安排,
必定得到从该活动的结束之间至最后个活动的结束时间的最大安排范围.
即为后面的活动创造最大的安排空间.
至此,问题已经简化为第二个活动到最后一个活动的最优安排.
以此迭代,最终得到每个活动的安排时间范围以及最大可容纳的活动数量.
所以此每一步的最优选择,必然会推至整体最优解.


源代码:

#include 
#include 
#include 
using namespace std;

struct GREEDY
{
	int s;
	int f;
};

void Sort(GREEDY *g,int n)
{
	int i,j;
	GREEDY tmp;
	
	for(i=1;i<=n;i++)
	for(j=i;j<=n;j++)
	{
		if(g[i].f>g[j].f)
		{
			tmp=g[i];
			g[i]=g[j];
			g[j]=tmp;
		}
		if(g[i].f==g[j].f)
		{
			if((g[i].f-g[i].s)<(g[j].f-g[j].s))
			{
				tmp=g[i];
				g[i]=g[j];
				g[j]=tmp;
			}
		}
	}
	
}

int GreedySelector(int n,GREEDY *g)
{
	int i,j=1,counts=1;
	for(i=2;i<=n;i++)
		if(g[i].s>=g[j].f) 
		{
			j=i;
			counts++;
		}
	return counts;
}

int main()
{
	int n,i;
	GREEDY *gre=new GREEDY[1001];
	
	while(scanf("%I64d",&n) && n)
	{	
		for(i=1;i<=n;i++) scanf("%d%d",&gre[i].s,&gre[i].f);
		
		Sort(gre,n);
		
		printf("%d\n",GreedySelector(n,gre));
	}
	
	return 0;
}


你可能感兴趣的:(ACM解题报告)