好的,我不会用正确的代码来回答这个问题,而且在我尝试定义我对问题的理解时,我最多会有伪代码。我还将假设您将使用整数时间,而不是浮点时间,尽管我确信它在一天结束时不会产生巨大的差异。
这里的贪婪解决方案是简单地分配到一个免费的报告厅,并且总是使用以前使用过的报告厅。也就是说,我很确定解决方案要求您做什么。
所以,首先,我会创建某种struct
或class
包含所有“事件”的东西,我们将“事件”定义为活动的开始时间或结束时间。这个struct
/class
也将引用它是什么活动的开始/结束时间。
也许有点像(C++ 语法,因为它更容易而且我很懒):
struct evt
{
int activityID;
int time;
bool isStart;
};
下一步将是为此struct
或class
每个活动的开始/结束时间构造一个实例,然后将其放入某种列表数据结构中(如果这是 C++,我会使用 a vector
,我猜ArrayList
是 Java)和然后根据事件对事件进行排序time
。因此,对于 Java,您需要某种比较函数来根据这些事件的时间确定它们的顺序。此外,在您的比较器中,作为开始事件的事件将晚于作为结束事件的事件(请记住,间隔是半开的)。我会打电话给ArrayList
“ eventList
”。
接下来,您有两个列表,我假设是n 个大厅(您最多需要n 个大厅来运行所有活动)。一份清单列出了所有大厅。这是未使用的大厅列表。另一个列表是空的。这将是正在使用的大厅列表。这些将是可以从前面删除的列表(ArrayList
我认为 Java 可以做到这一点)。
您将有某种方法来识别大厅,也许还有某种参考数组,以便可以将每个活动分配给一个大厅。这部分有点不清楚,我宁愿把实现细节留给你,但如果n不是太大,我可能会(再次使用 C++) avector<int>
大小为n,以及其中的第i个元素vector
将是大厅标识符,或者-1
尚未分配。如果我在 Java 中尝试这个,这将是一个int[n]
数组。
然后我会遍历eventList
,并且在每个事件中,我会检查它是结束时间还是开始时间。如果是开始时间,我会将“空闲大厅”列表的最前面的元素放入“使用中”大厅。如果是完成时间,我会把刚刚完成的大厅,从“使用中”列表中删除,然后放回“空闲大厅”列表的前面。请记住,您还需要更新我之前谈到的那个引用数组。
最后,稍微修改一下,你就可以知道使用了多少个大厅。在您使用大厅时,线性穿过阵列或正在运行的计数器就足够了。我认为可行的一种方法是记录一次包含多少个大厅正在使用的列表的最大大小,尽管这可能不正确(尚未彻底测试)。
我只是在想办法做到这一点,所以这个解决方案目前可能有点令人困惑。对于那个很抱歉。我会在这里尝试总结一下:
- 声明一个将开始/结束时间总结为事件的类
- 将所有开始和结束时间排序到一个数组中,较早的时间在列表中较早,结束时间出现在开始时间之前
- 制作一个大厅列表,另一个(空列表)将是所有正在使用的大厅
- 处理每个事件,如果是开始时间,则将大厅移动到使用列表,如果是结束时间,则移动到空闲列表
由于这是一篇很长的帖子,而且我没有提供太多代码(我尝试过提示,但我不知道它是否有帮助)如果您有更多问题,请告诉我,我会尽力提供帮助能够。
在这里看到的“活动选择”问题可以通过总是选择最早完成的活动以贪婪的方式解决。我认为这有点不同,但我只是将其包括在内,因为它可能很有趣。