Em uma linha numérica de comprimento M
, em que 0 < M <= 1,000,000,000
você forneceu N
( 1 < N <= 100,000
) pares inteiros de pontos. Em cada par, o primeiro ponto representa onde um objeto está localizado atualmente e o segundo ponto representa para onde um objeto deve ser movido. (Lembre-se de que o second
ponto pode ser menor que o first
).
Agora, suponha que você comece no ponto 0
e tenha um carrinho que possa conter 1
objetos. Você deseja mover todos os objetos de suas posições iniciais para suas respectivas posições finais enquanto percorre a menor distância ao longo da linha numérica ( não deslocamento). Você tem que acabar no ponto M
.
Agora, estou tentando reduzir esse problema para um problema mais simples. Para ser sincero, nem consigo pensar em uma solução de força bruta ( possivelmente gananciosa). No entanto, meu primeiro pensamento foi degenerar um movimento para trás em dois movimentos para frente, mas isso não parece funcionar em todos os casos.
Eu desenhei esses 3
casos de teste de amostra aqui:
A resposta para o primeiro caso de teste é 12
. Primeiro, você escolhe o red
item no ponto 0
. Então você vai para o ponto 6
(distância = 6
), solta o red
item temporariamente e, em seguida, pega o green
item. Então você vai para o ponto 5
(distância = 1
) e solta o green
item. Então você volta ao ponto 6
(distância = 1
) e pega o red
item que caiu, passa ao ponto 9 (distância = 3
) e depois ao ponto 10
(distância = 1
) para finalizar a sequência.
A distância total percorrida foi 6 + 1 + 1 + 3 + 1 = 12
, que é a distância mínima possível.
Os outros dois casos têm respostas 12
, acredito. No entanto, não consigo encontrar uma regra geral para resolvê-lo.
Alguém tem alguma idéia?
fonte
Respostas:
Se você estiver vazio, comece a se mover para a direita.
Sempre que você alcançar um objeto e estiver vazio, pegue-o (duh) e vá em direção ao seu destino.
Sempre que você alcançar um objeto
a
e já estiver carregandob
, sempre escolha um dos objetos com o destino numericamente menor (mais à esquerda).Se você ainda não está na M, volte para a etapa 1.
Isso é ideal: o único lugar onde você tem uma escolha real é na etapa 3. O primeiro destino do lado esquerdo garante que, quando você despachar os dois objetos, você estará o mais à direita possível.
Por que essa pergunta está no programmers.sx? Sim, "pergunta da entrevista", mas é apenas um bom enigma.
PS. Em termos de implementação, tudo que você precisa é a lista de tarefas (os pares inteiros de pontos) classificadas pela posição original.
fonte
Suponha que você receba esses movimentos,
(a, b), (c, d), (e, f), ...
então a distância mínima a ser percorrida éabs(b - a) + abs(d - c) + abs(f - e) + ...
a distância real percorridaabs(b - a) + abs(c - b) + abs(d - c) + abs(e - d) + ...
.Basicamente, dado um conjunto de movimentos, o objetivo é minimizar a função "distância da viagem" trocando elementos. Se você considerar uma combinação específica como um nó e todas as combinações que podem ser alcançadas como arestas, poderá usar um dos muitos algoritmos de pesquisa de gráficos em torno dos quais utiliza uma heurística. Um exemplo é a busca por vigas .
fonte
Pode ser que eu esteja entendendo mal o problema, mas e o seguinte:
O fato de ser classificado garante que você não avance e avance os elementos para colocá-los no local apropriado (independentemente se a linha estiver representada como uma matriz ou lista)
Atualizar após o comentário @templatetypedef:
use a
HashTable
para armazenar todos os pares. Use a localização atual de cada par como chave de índice.Use um segundo índice sobre os pares.
fonte
Minha inclinação para um algoritmo que é basicamente ganancioso:
Crie uma lista de pontos que precisam ser movidos. Como otimizar isso não faz parte do problema necessário, não vou me preocupar em organizá-lo.
Eu acho que isso cobre todos os casos. Em certo sentido, é recursivo, mas através da atualização da lista, em vez de se chamar.
fonte
Destination = SubList.FindSmallest(Location, Move.Origin)
? O queMove.Origin
representa?Esse é o problema do vendedor ambulante assimétrico . Você pode pensar nisso como um gráfico. As arestas serão cada par (início, término), um para cada (0, início) e todos os outros pares de (término, início).
Supondo que NP! = P, ele terá um tempo de execução esperado exponencial.
fonte
M
está o ponto final da linha numérica?N
pode ser 100.000.