En una recta numérica de longitud M
, donde 0 < M <= 1,000,000,000
, le dio N
( 1 < N <= 100,000
) pares enteros de puntos. En cada par, el primer punto representa dónde se encuentra actualmente un objeto y el segundo punto representa dónde se debe mover un objeto. (Tenga en cuenta que el second
punto puede ser más pequeño que el first
).
Ahora, suponga que comienza en el punto 0
y tiene un carrito que puede contener 1
objetos. Desea mover todos los objetos desde sus posiciones iniciales a sus respectivas posiciones finales mientras recorre la menor distancia a lo largo de la recta numérica ( no desplazamiento). Tienes que terminar a punto M
.
Ahora, he estado tratando de reducir este problema a un problema más simple. Para ser sincero, ni siquiera puedo pensar en una solución de fuerza bruta ( posiblemente codiciosa). Sin embargo, mi primer pensamiento fue degenerar un movimiento hacia atrás a dos movimientos hacia adelante, pero eso no parece funcionar en todos los casos.
Dibujé estos 3
casos de prueba de muestra aquí:
La respuesta al primer caso de prueba es 12
. Primero, recoges el red
artículo en el punto 0
. Luego te mueves al punto 6
(distancia = 6
), sueltas el red
artículo temporalmente y luego lo recoges green
. Luego te mueves al punto 5
(distancia = 1
) y sueltas el green
elemento. Luego regresa al punto 6
(distancia = 1
) y recoge el red
elemento que dejó caer, vaya al punto 9 (distancia = 3
), luego vaya al punto 10
(distancia = 1
) para finalizar la secuencia.
La distancia total recorrida fue 6 + 1 + 1 + 3 + 1 = 12
, que es la distancia mínima posible.
Los otros dos casos tienen respuestas 12
, creo. Sin embargo, no puedo encontrar una regla general para resolverlo.
¿Alguien tiene alguna idea?
fuente
Respuestas:
Si está vacío, comience a moverse hacia la derecha.
Siempre que alcances un objeto y estés vacío, recógelo (duh) y muévete hacia su destino.
Siempre que llegue a un objeto
a
y ya lo esté cargandob
, elija siempre el objeto que tenga el destino numéricamente más pequeño (más a la izquierda).Si aún no estás en M, vuelve al paso 1.
Esto es óptimo: el único lugar donde tiene una opción real es en el paso 3. El manejo del destino más a la izquierda primero asegura que para cuando haya despachado ambos objetos, estará lo más a la derecha posible.
¿Por qué esta pregunta está en programmers.sx? Sí, "pregunta de entrevista", pero es un buen acertijo.
PD. En términos de implementación, todo lo que necesita es la lista de tareas (los pares de puntos enteros) ordenadas por posición original.
fuente
Suponga que le dan estos movimientos,
(a, b), (c, d), (e, f), ...
entonces la distancia mínima que tiene que viajar esabs(b - a) + abs(d - c) + abs(f - e) + ...
y la distancia real que viajaabs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ...
.Básicamente, dada una serie de movimientos, el punto es minimizar la función de "distancia de viaje" intercambiando elementos. Si considera una combinación particular como un nodo y todas las combinaciones que puede alcanzar desde él como bordes, puede usar uno de los muchos algoritmos de búsqueda de gráficos alrededor del cual se utiliza una heurística. Un ejemplo es la búsqueda de haz .
fuente
Puede ser que no entienda bien el problema, pero ¿qué pasa con lo siguiente?
El hecho de que esté ordenado garantiza que no vaya de un lado a otro de los elementos para colocarlos en la ubicación adecuada (independientemente de si la línea se representa como una matriz o lista)
Actualización después del comentario @templatetypedef:
use a
HashTable
para almacenar todos los pares. Use la ubicación actual de cada par como clave de índice.Use un segundo índice sobre los pares.
fuente
Mi inclinación hacia un algoritmo que es básicamente codicioso:
Crea una lista de puntos que necesites mover. Dado que optimizar esto no es parte del problema requerido, no me preocuparé de organizarlo.
Creo que esto cubre todos los casos. En cierto sentido, es recursivo, pero a través de la actualización de su lista en lugar de llamarse a sí mismo.
fuente
Destination = SubList.FindSmallest(Location, Move.Origin)
? ¿QuéMove.Origin
representa?Este es el problema asimétrico del vendedor ambulante . Puedes pensar en esto como un gráfico. Los bordes serán cada par (inicio, finalización), uno para cada (0, inicio) y todos los demás pares de (finalización, inicio).
Suponiendo que NP! = P, tendrá un tiempo de ejecución esperado exponencial.
fuente
M
está el punto final de la recta numérica?N
puede ser 100,000.