Недавно я выполнил следующее упражнение на собеседовании:
«Робота можно запрограммировать на пробежку «а», «б», «в»… «n» километров, и он занимает t a, t b, t c... t nминут соответственно. Как только он пробежит запрограммированные километры, его нужно выключить на «m» минут.
Через «m» минут его можно снова запрограммировать на прохождение еще «a», «b», «c»… «n» километров.
Как бы вы запрограммировали этого робота, чтобы он прошел точное количество километров за минимальное время?
Я думал, что это вариация задачи о неограниченном рюкзаке, в которой размером будет количество километров, а значением будет время, необходимое для завершения каждого участка. Основное отличие состоит в том, что нам нужно минимизировать, а не максимизировать значение. Поэтому я использовал эквивалент следующего решения: http://en.wikipedia.org/wiki/Knapsack_problem#Unbounded_knapsack_problem
в котором я выбираю минимум.
Наконец, поскольку нам нужно точное решение (если оно существует), по карте, построенной с помощью алгоритма для всех различных расстояний, я перебрал каждое запрограммированное расстояние каждого робота, чтобы найти точное расстояние и минимальное время между ними. те.
Я думаю, что пауза, которую робот делает между запусками, является чем-то вроде отвлекающего маневра, и вам просто нужно включить ее в свои расчеты, но она не влияет на выбранный подход.
Вероятно, я ошибаюсь, потому что провалил тест. У меня нет других отзывов об ожидаемом решении.
Редактировать: возможно, я все-таки не ошибся и потерпел неудачу по другим причинам. Я просто хотел подтвердить свой подход к этой проблеме.
import static com.google.common.collect.Sets.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public final class Robot {
static final Logger logger = Logger.getLogger (Robot.class);
private Set programmedRuns;
private int pause;
private int totalDistance;
private Robot () {
//don't expose default constructor & prevent subclassing
}
private Robot (int[] programmedDistances, int[] timesPerDistance, int pause, int totalDistance) {
this.programmedRuns = newHashSet ();
for (int i = 0; i < programmedDistances.length; i++) {
this.programmedRuns.add (new ProgrammedRun (programmedDistances [i], timesPerDistance [i] ) );
}
this.pause = pause;
this.totalDistance = totalDistance;
}
public static Robot create (int[] programmedDistances, int[] timesPerDistance, int pause, int totalDistance) {
Preconditions.checkArgument (programmedDistances.length == timesPerDistance.length);
Preconditions.checkArgument (pause >= 0);
Preconditions.checkArgument (totalDistance >= 0);
return new Robot (programmedDistances, timesPerDistance, pause, totalDistance);
}
/**
* @returns null if no strategy was found. An empty map if distance is zero. A
* map with the programmed runs as keys and number of time they need to be run
* as value.
*
*/
Map calculateOptimalStrategy () {
//for efficiency, consider this case first
if (this.totalDistance == 0) {
return Maps.newHashMap ();
}
//list of solutions for different distances. Element "i" of the list is the best set of runs that cover at least "i" kilometers
List