挤奶问题,贪心算法的简单应用
最近有一些同学后台留言:小楼同学,我学会了贪心算法,但是不知道怎么使用,能不能讲一下贪心算法的使用案例呢?大家对学习的渴望就是小楼同学发文的动力。小楼同学先带大家看一道简单的题目。
题目选自poj:
有n头牛(1<=n<=50,000)要挤奶。给定每头牛挤奶的时间区间[A,B](1<=A<=B<=1,000,000,A,B为整数)。
牛需要待在畜栏里才能挤奶。一个畜栏同一时间只能容纳一头牛,问至少需要多少个畜栏,才能完成全部挤奶工作,以及每头牛都放哪个畜栏里。
去同一个一个畜栏的两头牛,它们挤奶时间区间哪怕只在断点重合也是不可以的。
还记得使用贪心算法的三个步骤吗?
分解问题:
将问题“需要多少个畜栏”转化为如何为每个奶牛分配畜栏。
寻找每一步的最优解:
每次如果有空余的畜栏,就将牛放在其中。如果没有,就为牛新设一个畜栏。
叠加得到完整解:
为每个奶牛都分配畜栏后,统计畜栏的总量。因为按时间处理奶牛是必然的,在没有空余的畜栏时,为奶牛设立新畜栏是唯一选择。所以用贪心算法求得的是最优解。
因为我们是学习数学建模,而不是做算法题,如何输入输出取决于实际的情况和要求。而不是像算法比赛中读取题目所给的数据。为了方便大家理解,本程序中仅设置10个奶牛。开始结束时间分别为:(1,2),(2,4),(3,4),(4,6),(6,12),(10,15),(12,17),(15,19),(16,17),(17,20)。
实际解决问题时如果数据过多,小楼同学建议大家把数据储存在excel表中,然后再用matlab读取。
matlab代码如下:
%实部为开始时间,虚部为结束时间
time=[17+20i,2+4i,3+4i,6+12i,4+6i,10+15i,15+19i,12+17i,16+17i,1+2i];
%畜栏矩阵,储存结束时间
corral=[0];
%将time从小到大排列后的矩阵赋给T
T=sort(time);
for i=1:length(time)
if real(T(1,i))>corral(1,1)
corral(1,1)=imag(T(1,i));
else
corral=[corral imag(T(1,i))];
end
corral=sort(corral);
end
%corral的长度就是所需畜栏的数量
length(corral)