题目描述:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场,设计一个有效的贪心算法进行
安排。
思路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;
}