51nod-1428活动安排问题题解--Java&&Python

如下图所示,是我在51nod上做到的算法题,一道典型的贪心算法题。因此,在这里跟大家讲解一下我的思路。


思路:可以课程根据开始时间进行升序排序,依次对课程进行处理,并用一个数组存储教室,保存的是教室当前课程的结束时间。进行处理每堂课时,则需要对教室进行遍历,查看该课程的开始时间是否大于该教室的前一课程的结束时间,是的话求差值,并记录位置,当遍历所有教室结束后,更新差值最小的教室,将结束时间更新为该课程的结束时间,如果所有教室都没有合适的,则增加教室,并将该教室结束时间设置为该课程的结束时间。直到遍历所有的课程,得到的便是最少的教室。

代码:

Java版本:

package arrangeclassroom;
import java.util.*;

public class ArrangeClassroom {
	
	public static void sort(int[][] old,final int[] order)//重写sort方法,使其支持多列排序,即多个关键字排序
	{
		Arrays.sort(old, new Comparator<Object>() {
			public int compare(Object o1,Object o2)
			{
				int[] one=(int[])o1;
				int[] two=(int[])o2;
				for(int i=0;i<order.length;i++)
				{
					int k=order[i];
					if(one[k]>two[k])
						return 1;
					else if(one[k]<two[k])
						return -1;
					else continue;
				}
				return 0;
			}
		});
	}
	
	public static int arrangeClassroom(int[][] time,int n)
	{
		sort(time,new int[] {0,1});
		int[] ans=new int[n];
		ans[0]=time[0][1];
		int count=0;
		for(int i=1;i<n;i++)
		{
			int w=0;
			int min_num=Integer.MAX_VALUE;//用min_num记录不冲突的但间隔时间最短的教室,体现了贪心思想。
			boolean flag=false;
			for(int j=0;j<count+1;j++)
			{
				if(time[i][0]>=ans[j])
				{
					flag=true;
					if(time[i][0]-ans[j]<min_num)
					{
						min_num=time[i][0]-ans[j];
						w=j;
					}
				}
				
			}
			if(flag)
				ans[w]=time[i][1];
			else
			{
				count++;
				ans[count]=time[i][1];
			}
		}
		return count+1;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		String[] str=sc.nextLine().split(" ");
		int n=Integer.parseInt(str[0]);
		int[][] time=new int[n][2];
		for(int i=0;i<n;i++)
		{
			String[] str1=sc.nextLine().split(" ");
			time[i][0]=Integer.parseInt(str1[0]);
			time[i][1]=Integer.parseInt(str1[1]);
		}
		System.out.println(arrangeClassroom(time,n));

	}

}


测试结果:

3
1 2
3 4
2 9
2

Python版本:

#-*-coding:utf-8 -*-
import bisect
while True:
    try:
        n=int(raw_input())
        res=[]
        for i in range(n):
            m=map(int,raw_input().split())
            res.append(m)
        res=sorted(res,key=lambda x:(x[0],x[1]))//根据课程的开始时间进行排序
        r1=res[0][1]
        ans=[r1]
        for u in res[1:]:
            k,h=u
            if k<ans[0]:
                ans=[h]+ans
                ans.sort()
            else:
                idx=bisect.bisect(ans,k)
                ans[idx-1]=h
                ans.sort()
        print len(ans)
    except:
        break

测试结果:

3
1 2
3 4
2 9
2
本题主要体现的是贪心思想,是一个区间着色问题,思考的过程中,则希望每个教室都比较紧凑,即空隙时间达到最少,所以考虑到了根据开始时间最少来进行排序,然后根据遍历的课程与教室的结束时间进行比较,求不冲突并且间隙最小的教室,从而使得整体的教室能够最少。其实本题还有一种思路:即对结束时间进行排序,对于结束时间相同的,则按开始时间进行排序,升序排序。遍历思路则与前面提到的相同,都是通过维护教室的结束时间。

转发请注明:转自http://blog.csdn.net/carson0408/article/details/78686707

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值