Мой друг недавно столкнулся с этой проблемой в техническом интервью.
Название проблемы - Длинный перерыв
Вы организуете мероприятие, на котором будет несколько докладчиков. Событие начинается в момент времени 0, и время будет выделено для
сеть в любое время во время мероприятия, когда нет
презентация делается. Презентации не могут перекрываться, поскольку они
в той же комнате, но это позволяет им работать последовательно, без
брейки. Хотя порядок выступлений не может быть изменен, существует
максимальное число, которое указывает, сколько речей может быть
перенесено. Ваша цель - максимизировать длину самого длинного
Сетевой период вы можете организовать. Например, есть n = 4
ведущие запланированы на ход мероприятия, которое начинается во время
0 и заканчивается в момент времени t = 15. Встречи начинаются в моменты времени start = [4, 6,
7, 10] и заканчиваются время от времени отделкой = [5, 7, 8, 11]. Вы можете переставить
к = 2 встречи. Зеленые клетки свободны, помечены номером часа,
и синие клетки имеют запланированную презентацию, отмеченную презентацией
число.
![enter image description here](https://i.stack.imgur.com/eKhOw.png)
В этом случае у нас запланировано 4 периода без выступающих: [(0-3), (5), (8-9), (11-14)]. Встреча заканчивается через 14 часов. Если первый
Встреча перенесена на час позже, создается перерыв от 0 до 5, 5
ч. Если последняя речь перемещается до 8, она заканчивается в 9, оставляя
перерыв с 9 на 15. Нет смысла сдвигать средние два
речи в этом случае. Самый длинный перерыв, который может быть достигнут - 15 -
9 = 6 часов, перенося последнюю речь на два часа раньше. Два
варианты показаны ниже.
К сожалению, мне не удалось сопоставить проблему со стандартной. Я попробовал свою собственную наивную реализацию, которая, кажется, хорошо работает для данного ввода (пришлось изменить стратегию для крайних случаев)
Вот моя реализация
import java.util.ArrayList;
import java.util.Iterator;
class Test {
public static void main(String args[]) {
Test T = new Test();
int n = 4;
int k = 2;
int start[] = {4, 6, 7, 10};
int end[] = {5, 7, 8, 11};
int t = 15;
System.out.println(T.findBreakDuration(n, k, start, end, t));
}
int findBreakDuration(int n, int k, int start[], int end[], int t) {
boolean meetings[] = new boolean[t]; // false means empty slot
int i = 0;
while (i < n) {
for (int j = start[i]; j < end[i]; j++)
meetings[j] = true;
i++;
}
ArrayList<Integer> emptySlots = new ArrayList<Integer>();
int count = 0;
for (i = 0; i < meetings.length; i++) {
if (!meetings[i])
count++;
else {
if (count > 0) {
emptySlots.add(count);
count = 0;
}
}
}
if (count > 0)
emptySlots.add(count);
if(emptySlots.size()<=1)
return -1;
int maxSoFar = Integer.MIN_VALUE;
for(i = 0;i<emptySlots.size();i++){
int e = emptySlots.get(i);
if(e<=k){
if(i==0){
int increasedRight = e + emptySlots.get(i+1);
if(maxSoFar<increasedRight)
maxSoFar = increasedRight;
}
else if(i==emptySlots.size()-1)
{
int increasedLeft = e + emptySlots.get(i-1);
if(maxSoFar<increasedLeft)
maxSoFar = increasedLeft;
}
else{
int increasedLeft = e + emptySlots.get(i-1);
int increasedRight = e + emptySlots.get(i+1);
if(maxSoFar<increasedLeft)
maxSoFar = increasedLeft;
if(maxSoFar<increasedRight)
maxSoFar = increasedRight;
}
}
}
return maxSoFar; // Output : 6, in this case
}
}
Краткое описание вышеприведенного кода -
Я просто отслеживаю пустые слоты и сравниваю максимально доступный слот после допустимой перестановки (т.е. <= k). Окончательное максимальное значение дает мне максимально возможную длину или максимальную продолжительность последовательности пустых слотов. </em>
Я знаю, что это очень наивная реализация, и я уверен, что есть лучший и элегантный способ решения проблемы. У меня очень сильное чувство, что я упускаю что-то элементарное здесь. Есть ли способ решить эту проблему элегантным способом?