让我们假设我们有N名考官和一组k学生。我需要每个考官来检查学生的时间存储在A [i]。 我们的任务是找到检查所有学生和检查队列中最后一名学生所需的总时间。每位考官一次只能检查一名学生。附加限制:如果不超过1名检查员在学生的陪同下,下一个学生去第一个可能的考官(见例子的第4步)
举个例子,如果我们有N = 2名审查员和k = 4名学生,第一名审查员每个学生需要10分钟(A [1] = 10),第二名审查员每个学生需要5分钟(A [2] = 5),然后:
步骤1:学生1在时间0前往考官1
步骤2:学生2也在时间0前往考官2
步骤3:学生3在时间5到考官2,因为学生2已经完成
步骤4:学生4可以在10时间到考官1或考官2,因为两者都已完成。由于我们的额外限制,他去了考官1
步骤5:学生4在时间20结束
所以程序应该作为输出返回:time = 20,examiner = 1
到目前为止,我已经想到了O(nk)算法:
if(n>=k) //if examiners more than students ,it's simple
{
for(i=1;i<=k;i++)
B[i]=A[i];
p=max_position(B); //find maximum of first k elements
printf("%d,B[p]); //required time
return(k); //kth student goes to kth examiner
}
else
{
for(i=1;i<=n;i++)
B[i]=A[i]; //create copy of A
int t=0;
for(i=1;i<=k-n;i++) //n students already gone to examiners in time 0
{
int p = min_position(B); //finds position of minimum element
B[p]=B[p]+A[p];
time = B[p];
}
printf("%d ,time);
return(p);
}
有没有办法比O(nk)更快地完成它?
答案 0 :(得分:1)
您可以随时以下列方式向所有审核员创建订单:
之前可用的审查员是&#34;较小&#34;而不是以后可用的。 (这可以表示审查员获得自由的时间)
如果两个审查员同时可用,那么索引较小的审查员就会更小&#34;
使用此顺序,您可以构建一个存储所有审查员的最小堆,并为每个学生拉动堆顶部的审查员(最小的),然后将其插入堆然后再添加执行所需的时间。考试。
此解决方案将在O(klogn)中运行。