Auf einer Zahlenlinie der Länge M
haben 0 < M <= 1,000,000,000
Sie N
( 1 < N <= 100,000
) ganzzahlige Punktepaare angegeben. In jedem Paar repräsentiert der erste Punkt, wo sich ein Objekt gerade befindet, und der zweite Punkt repräsentiert, wo ein Objekt bewegt werden soll. (Beachten Sie, dass der second
Punkt möglicherweise kleiner als der ist first
).
Angenommen, Sie beginnen an der Stelle 0
und haben einen Wagen, der 1
Objekte aufnehmen kann. Sie möchten alle Objekte von ihren Anfangspositionen zu ihren jeweiligen Endpositionen verschieben, während Sie die geringste Strecke entlang der Zahlenlinie zurücklegen ( keine Verschiebung). Sie müssen auf den Punkt kommen M
.
Jetzt habe ich versucht, dieses Problem auf ein einfacheres Problem zu reduzieren. Um ehrlich zu sein, kann ich mir nicht einmal eine Brute-Force- Lösung ( möglicherweise gierig) vorstellen. Mein erster Gedanke war jedoch, eine Rückwärtsbewegung in zwei Vorwärtsbewegungen zu degenerieren, aber das scheint nicht in allen Fällen zu funktionieren.
Ich habe diese 3
Beispieltestfälle hier herausgezogen:
Die Antwort auf den ersten Testfall lautet 12
. Zuerst holen Sie den red
Gegenstand an der Stelle ab 0
. Dann bewegen Sie sich zum Punkt 6
(Entfernung = 6
), lassen den red
Gegenstand vorübergehend fallen und nehmen den green
Gegenstand auf. Dann bewegen Sie sich zum Punkt 5
(Abstand = 1
) und lassen den green
Gegenstand fallen. Dann gehen Sie zurück zu Punkt 6
(Entfernung = 1
) und nehmen den red
Gegenstand auf, den Sie fallen gelassen haben. Gehen Sie zu Punkt 9 (Entfernung = 3
) und dann zu Punkt 10
(Entfernung = 1
), um die Sequenz zu beenden.
Die zurückgelegte Gesamtstrecke war 6 + 1 + 1 + 3 + 1 = 12
die minimal mögliche Entfernung.
Die beiden anderen Fälle haben Antworten auf 12
, glaube ich. Ich kann jedoch keine allgemeine Regel finden, um das Problem zu lösen.
Hat jemand irgendwelche Ideen?
quelle
Antworten:
Wenn Sie leer sind, bewegen Sie sich nach rechts.
Wenn Sie ein Objekt erreichen und leer sind, heben Sie es auf (duh) und bewegen Sie sich in Richtung seines Ziels.
Jedes Mal , wenn Sie ein Objekt zu erreichen
a
und Sie bereits tragenb
, immer wählen , je nachdem , welche der Objekte die numerisch kleinste Ziel hat ( am weitesten links).Wenn Sie noch nicht bei M sind, fahren Sie mit Schritt 1 fort.
Dies ist optimal: Der einzige Ort, an dem Sie eine echte Auswahl haben, ist Schritt 3. Wenn Sie zuerst das Ziel ganz links behandeln, stellen Sie sicher, dass Sie sich zum Zeitpunkt des Versands beider Objekte so weit wie möglich rechts befinden.
Warum ist diese Frage auf programmers.sx? Ja, "Interviewfrage", aber es ist nur ein schönes Rätsel.
PS. Für die Implementierung benötigen Sie lediglich eine Liste der Aufgaben (die ganzzahligen Punktepaare), die nach der ursprünglichen Position sortiert sind.
quelle
Angenommen, Sie erhalten diese Bewegungen,
(a, b), (c, d), (e, f), ...
dann ist die Mindestentfernung, die Sie zurücklegen müssen,abs(b - a) + abs(d - c) + abs(f - e) + ...
und die tatsächliche Entfernung, die Sie zurücklegenabs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ...
.Grundsätzlich besteht der Punkt bei einer Reihe von Bewegungen darin, die Funktion "Fahrstrecke" durch Vertauschen von Elementen zu minimieren. Wenn Sie eine bestimmte Kombination als Knoten betrachten und alle Kombinationen, die Sie daraus als Kanten erreichen können, können Sie einen der vielen Graphensuchalgorithmen verwenden, um die herum eine Heuristik verwendet wird. Ein Beispiel ist die Strahlensuche .
quelle
Vielleicht verstehe ich das Problem falsch, aber was ist mit Folgendem:
Die Tatsache, dass es sortiert ist, garantiert, dass Sie die Elemente nicht hin und her bewegen, um sie an der richtigen Stelle zu platzieren (unabhängig davon, ob die Linie als Array oder Liste dargestellt wird).
Update nach @ templatetypedef Kommentar:
Verwenden Sie a
HashTable
, um alle Paare zu speichern. Verwenden Sie die aktuelle Position jedes Paares als Indexschlüssel.Verwenden Sie einen zweiten Index über den Paaren.
quelle
Meine Neigung zu einem Algorithmus, der grundsätzlich gierig ist:
Erstellen Sie eine Liste mit Punkten, die verschoben werden müssen. Da die Optimierung nicht Teil des erforderlichen Problems ist, werde ich mich nicht um die Organisation kümmern.
Ich denke, das deckt alle Fälle ab. In gewisser Weise ist es rekursiv, aber durch Aktualisieren der Liste, anstatt sich selbst aufzurufen.
quelle
Destination = SubList.FindSmallest(Location, Move.Origin)
? Was bedeutetMove.Origin
?Dies ist das asymmetrische Problem des Handlungsreisenden . Sie können sich dies als Grafik vorstellen. Die Kanten sind jedes Paar (Start, Ende), eines für jedes Paar (0, Start) und alle anderen Paare von (Ende, Start).
Unter der Annahme von NP! = P hat es eine exponentiell erwartete Laufzeit.
quelle
M
ist der Endpunkt der Zahlenlinie?N
da er 100.000 betragen kann.