会议安排问题

题目描述:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场,设计一个有效的贪心算法进行

安排。

思路1:

对待安排的活动,按照开始时间的先后顺序进行排序, 开始时间早的排在前面。然后,假定以每一个活动

作为第一个活动来安排,找出下一个最早结束的活动,直到遍历到最后一个活动为止。取安排的活动的最大值。

	int arrange(int[][] schedule)
	{
		if (schedule == null)
			return 0;
		
		// 对传入的时间表按照开始时间,从前向后的顺序进行排序
		sortByStartTime(schedule);
		
		int endTime = 0; // 会议的结束时间
		int ncount = 1; // 可以安排的会议的场数
		int curPos = 0; // 当前会议
		int earlyEndTime = Integer.MAX_VALUE; // 最早结束时间
		int maxArrange = 0; // 最多可以安排的会议数
		int i = 0, j = 0;
		for (i=0; i<schedule.length; i++)
		{
			ncount = 1;
			curPos = i;
			for (j=i+1; j<schedule.length; j++)
			{
				endTime = schedule[curPos][1]; // 这里的技巧
				// 下一个会议的开始时间要晚于前一个会议,并且结束时间要最早
				if (schedule[j][0] < endTime)
					continue;
				
				// 找出结束时间最早的会议
				earlyEndTime = Integer.MAX_VALUE;
				for (int k = j; k<schedule.length; k++)
				{
					if (earlyEndTime > schedule[k][1])
					{
						earlyEndTime = schedule[k][1]; // 取最早的结束时间
						curPos = k;
					}
				}
				ncount++; // 找到满足条件的下一个会议
				// 本次搜索到了最后一个会议
				if (curPos == schedule.length-1)
					break;
				j = curPos;
			}
			
			
			// 取最大的值
			maxArrange = Math.max(ncount, maxArrange);
		}
		return maxArrange;
	}
	
	// 按照开始时间对会议进行排序
	public void sortByStartTime(int[][] schedule)
	{
		int min = 0;
		int pos = 0;
		for (int i=0; i<schedule.length; i++)
		{
			min = schedule[i][0];
			pos = i;
			for (int j=i+1; j<schedule.length; j++)
			{
				if (schedule[j][0] < min)
				{
					min = schedule[j][0];
					pos = j;
				}
			}
			
			if (pos != i)
			{
				// 交换元素
				int tmp1 = schedule[i][0];
				int tmp2 = schedule[i][1];
				schedule[i][0] = schedule[pos][0];
				schedule[i][1] = schedule[pos][1];
				schedule[pos][0] = tmp1;
				schedule[pos][1] = tmp2;
			}
		}
	}

 思路2:贪心策略

class Meeting implements Comparator<Meeting>
{
	int startTime = 0; // 开始时间
	int endTime = 0;  // 结束时间
	int num = 0; // 会议编号
	
	public Meeting() {}
	
	public Meeting(int num, int startTime, int endTime)
	{
		this.startTime = startTime;
		this.endTime = endTime;
		this.num = num;
	}
	
	@Override
	public String toString()
	{
		return num +": "+startTime +" "+endTime;
	}

	@Override
	public int compare(Meeting m1, Meeting m2)
	{
		// 结束时间早的排在前面
		if (m1.endTime == m2.endTime)
			return m1.startTime - m2.startTime;
		return m1.endTime-m2.endTime;
	}
	
}

	int arrange(ArrayList<Meeting> schedule)
	{
		int n = schedule.size();
		// 按照会议开始时间的先后顺序排序
		Collections.sort(schedule, new Meeting());
		int ncount = 1;
		int last = schedule.get(0).endTime; // 第一个会议的结束时间
		// 开始选择会议
		for (int i=1; i<n; i++)
		{
			if (schedule.get(i).startTime > last)
			{
				ncount++;
				last = schedule.get(i).endTime;
			}
		}
		System.out.println(ncount);
		return ncount;
	}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值