问题描述
农场有n头牛,每头牛会有一个特定的时间区间[b,e]在蓄栏里挤牛奶,并且一个蓄栏里任何时刻只能有一头牛挤奶。
现在农场主希望知道最少蓄栏能够满足上述要求,并给出每头牛被安排的方案。对于多种可行方案,输出一种即可。
问题求解
牛的编号为1~n,每头牛的挤奶时间相当于一个活动,与前面活动安排问题不同,这里的活动时间是闭区间,例如[2,4]与[4,7]是交叉的,它们不是兼容活动。
采用与求解活动安排问题类似的贪心思路,将所有活动这样排序:结束时间相同按开始时间递增排序,否则按结束时间递增排序。
求出一个最大兼容活动子集,将它们安排在一个蓄栏中(蓄栏编号为1);如果没有安排完,再在剩余的活动再求下一个最大兼容活动子集,将它们安排在另一个蓄栏中(蓄栏编号为2),以此类推。
也就是说,最大兼容活动子集的个数就是最少蓄栏个数。
代码
struct Cow
{
int no;
int b;
int e;
bool operator<(const Cow &s)const
{
if(e==s.e)
return b<=s.b;
else
return e<=s.e;
}
};
int n=5;
Cow A[]={{0},{1,1,10},{2,2,4},{3,3,6},{4,5,8},{5,4,7}};
int ans[MAXN];
void solve()
{
sort(A+1,A+n+1);
memset(ans,0,sizeof(ans));
int num=1;
for(int i=1;i<=n;i++)
{
if(ans[i]==0)
{
ans[i]=num;
int preend=A[i].e;
for(int j=i+1;j<=n;j++)
{
if(A[j].b>preend&&ans[j]==0)
{
ans[j]=num;
preend=A[j].e;
}
}
num++;
}
}
}