Imagine que você está em um prédio alto com um gato. O gato pode sobreviver a uma queda de uma janela baixa, mas morrerá se jogado de um andar alto. Como você pode descobrir a queda mais longa que o gato pode sobreviver, usando o menor número de tentativas?
Obviamente, se você tiver apenas um gato, poderá pesquisar apenas linearmente. Primeiro jogue o gato do primeiro andar. Se sobreviver, jogue-o a partir do segundo. Eventualmente, depois de ser jogado do chão f, o gato morre. Você sabe que o piso f-1 era o piso seguro máximo.
Mas e se você tiver mais de um gato? Agora você pode tentar algum tipo de pesquisa logarítmica. Digamos que a construção tenha 100 andares e você tenha dois gatos idênticos. Se você atirar o primeiro gato para fora do 50º andar e ele morrer, será necessário procurar apenas 50 andares linearmente. Você pode melhorar ainda mais se escolher um piso inferior para sua primeira tentativa. Digamos que você opte por resolver o problema 20 andares por vez e que o primeiro andar fatal seja o número 50. Nesse caso, seu primeiro gato sobreviverá aos vôos dos andares 20 e 40 antes de morrer do andar 60. Você só precisa verificar os andares 41 a 49 individualmente. São 12 tentativas, o que é muito melhor do que as 50 que você precisaria se tentasse usar a eliminação binária.
Em geral, qual é a melhor estratégia e a pior complexidade possível para um edifício de dois andares com dois gatos? E quanto a n andares e m gatos?
Suponha que todos os gatos sejam equivalentes: todos sobreviverão ou morrerão de uma queda de uma determinada janela. Além disso, toda tentativa é independente: se um gato sobrevive a uma queda, é completamente ileso.
Isso não é tarefa de casa, embora eu possa ter resolvido isso uma vez na escola. É apenas um problema extravagante que me veio à cabeça hoje e não me lembro da solução. Pontos de bônus se alguém souber o nome desse problema ou do algoritmo da solução.
Respostas:
Você pode escrever facilmente um pouco de DP (programação dinâmica) para o caso geral de n andares e m gatos.
A fórmula principal,,
a[n][m] = min(max(a[k - 1][m - 1], a[n - k][m]) + 1) : for each k in 1..n
deve ser auto-explicativa:k - 1
andares para checar (todos abaixok
) em - 1
gatos (a[k - 1][m - 1]
).n - k
andares restantes (todos os andares acimak
) e aindam
gatos.max
.+ 1
vem do fato de que acabamos de usar uma tentativa (independentemente de o gato ter sobrevivido ou não).min(f(k)) : for k in 1..n
.Ele concorda com o resultado do Google no link de Gaurav Saxena para (100, 2).
Você pode encontrar facilmente a estratégia (como jogar o primeiro gato), se salvar melhor
k
em outra matriz.Também existe uma solução mais rápida, que não envolve cálculos de O (n ^ 3), mas já estou com um pouco de sono.
edit
Ah, sim, eu lembro onde vi esse problema antes .
fonte
+ 1
necessidade de ficar de fora damin()
? Como você diz, se a tentativa foi bem-sucedida ou não, ainda é uma tentativa.+1
fora demin
. Ou movê-lo dentro demax
:)De acordo com um episódio recente do Radiolab (sobre "Queda") , um gato atinge a velocidade terminal no 9º andar. Depois disso, relaxa e é menos provável que se machuque. Existem gatos completamente não lesionados após uma queda acima do dia 30. Os andares mais arriscados são do 5º ao 9º.
fonte
A melhor estratégia para resolver esse problema é investigar, usando a lei da física, a probabilidade de suas suposições serem verdadeiras em primeiro lugar.
Se você o tivesse feito, perceberia que as chances de sobrevivência do gato aumentam quanto maior a distância do solo. Obviamente, supondo que você o jogue de um edifício cada vez mais alto, como as torres petronas, e não de uma montanha cada vez mais alta, como o monte everest.
Edit:
Na verdade, você veria uma distribuição inacabada de camelos.
Primeiro, a probabilidade de o gato morrer é baixa (altitude muito baixa), depois fica mais alta (altitude baixa), depois mais baixa (altitude mais alta) e depois novamente mais alta (altitude muito alta).
O gráfico para a probabilidade de um gato morrer em função da altitude acima do solo é assim:
(termina em 3, porque a distribuição inacabada de camelos)
Atualização:
a velocidade terminal de um gato é de 100 km / h (60 mph) [= 27,7m / s = 25,4 jardas / s].
A velocidade terminal humana é de 210 km / h (130 mph). [= 75m / s = 68,58 jardas / s]
Fonte de velocidade terminal:
http://en.wikipedia.org/wiki/Cat_righting_reflex
Créditos:
Goooooogle
Preciso verificar mais tarde:
http://en.wikipedia.org/wiki/Terminal_velocity
http://www.grc.nasa.gov /WWW/K-12/airplane/termv.html
fonte
Li este problema pela primeira vez no Manual de design de algoritmos de Steven Skiena (exercício 8.15). Ele seguiu um capítulo sobre programação dinâmica, mas você não precisa conhecer programação dinâmica para provar limites precisos da estratégia . Primeiro a declaração do problema, depois a solução abaixo.
Apenas 1 ovo
Largar o ovo de cada andar, começando no primeiro, encontrará o andar crítico nas (na pior das hipóteses) n operações.
Não há algoritmo mais rápido. A qualquer momento em qualquer algoritmo, deixe g o andar mais alto a partir do qual o ovo não quebra. O algoritmo deve testar o piso g + 1 antes de qualquer piso superior h> g + 1; caso contrário, se o ovo sair do piso h, não será possível distinguir entre f = g + 1 ef = h.
2 ovos
Primeiro, vamos considerar o caso de k = 2 ovos, quando n = r ** 2 é um quadrado perfeito. Aqui está uma estratégia que leva tempo O (sqrt (n)). Comece largando o primeiro ovo em incrementos de r andares. Quando o primeiro ovo quebra, digamos no chão
ar
, sabemos que o piso crítico f deve estar(a-1)r < f <= ar
. Em seguida, largamos o segundo ovo de cada andar a partir de(a-1)r
. Quando o segundo ovo quebra, encontramos o piso crítico. Como eliminamos cada ovo no máximo r tempo, esse algoritmo leva na pior das operações 2r, que é Θ (sqrt (n)).Quando n não é um quadrado perfeito, use r =
ceil(sqrt(n)) ∈ Θ(sqrt(n))
. O algoritmo permanece Θ (sqrt (n)).Prova de que qualquer algoritmo leva pelo menos sqrt (n) tempo. Suponha que exista um algoritmo mais rápido. Considere a sequência de pisos a partir da qual ele solta o primeiro ovo (desde que não se quebre). Como cai menos que sqrt (n), deve haver um intervalo de pelo menos n / sqrt (n) que seja sqrt (n). Quando f está nesse intervalo, o algoritmo terá que investigá-lo com o segundo ovo, e isso deve ser feito passo a passo, lembrando o caso de 1 ovo. CONTRADIÇÃO.
k ovos
O algoritmo apresentado para 2 ovos pode ser facilmente estendido para k ovos. Largue cada ovo com intervalos constantes, que devem ser tomados como os poderes da k-ésima raiz de n. Por exemplo, para n = 1000 ek = 3, pesquise intervalos de 100 andares com o primeiro ovo, 10 com o segundo ovo e 1 com o último ovo.
Da mesma forma, podemos provar que nenhum algoritmo é mais rápido
Θ(n**(1/k))
induzindo a partir da prova k = 2.Solução exata
Deduzimos a recorrência otimizando onde soltar o primeiro ovo (piso g), presumindo que conhecemos soluções ideais para parâmetros menores. Se o ovo quebrar, temos o piso g-1 abaixo para explorar com ovos k-1. Se o ovo sobreviver, temos os andares acima para explorar com k ovos. O diabo escolhe o pior para nós. Assim, para k> 1, a recorrência
fonte
O(k*n**(1/k))
de execução para o pior caso? Já que, no pior dos casos, tenho que passarn**(1/k)
exatamente ok
tempo.Isso não pressupõe que você esteja usando "O mesmo gato"?
Você pode abordá-lo matematicamente, mas isso é bom na matemática ... com as suposições corretas, 0 pode ser igual a 1 (para valores grandes de 0).
Do ponto de vista prático, você pode obter 'Gatos Similares', mas não pode obter 'O Mesmo Gato'.
Você poderia tentar determinar a resposta empiricamente, mas eu pensaria que haveria diferenças estatísticas suficientes para que a resposta fosse estatisticamente sem sentido.
Você pode tentar usar "The Same Cat", mas isso não funcionaria, pois, após a primeira queda, não é mais o mesmo gato. (Da mesma forma, nunca se pode entrar no mesmo rio duas vezes)
Ou você pode agregar a saúde do gato, amostrando em intervalos extremamente próximos e encontrar as alturas para as quais o gato está "quase todo vivo" (ao contrário de "quase todo morto" de "The Princess Bride"). Os gatos sobreviverão, em média (até o último intervalo).
Acho que me desviei da intenção original, mas se você estiver seguindo o caminho empírico, voto por começar o mais alto possível e continuar a largar gatos à medida que a altura diminui até que eles sobrevivam estatisticamente. E, em seguida, teste novamente os gatos sobreviventes para ter certeza.
fonte
Eu tomei um método ligeiramente diferente para produzir uma solução.
Comecei por trabalhar fora do chão o máximo que poderia ser coberto usando x gatos e y suposições utilizando o seguinte método.
Comece com 1 andar e continue aumentando o número de palpites, mantendo o controle dos andares marcados, que acho que eles foram verificados e quantos gatos restavam para cada andar.
Repita isso até y vezes.
Este código muito ineficiente para calcular a resposta dada, mas ainda assim útil para um pequeno número de gatos / pisos.
Código Python:
Para 2 gatos, o piso máximo que pode ser identificado em x palpites é:
1, 3, 6, 10, 15, 21, 28 ...
Para 3 gatos:
1, 3, 7, 14, 25, 41, 63 ...
Para 4 gatos:
1, 3, 7, 15, 30, 56, 98 ...
Após uma extensa pesquisa (principalmente envolvendo digitar seqüências de números no OEIS ), notei que o número máximo de andares para x segue um padrão combinado de partes.
Para 2 gatos:
n <2: 2 ^ n - 1
n> = 2: C (n, 1) + C (n, 2)
Para 3 gatos:
n <3: 2 ^ n - 1
n> = 3: C (n, 1) + C (n, 2) + C (n, 3)
Para 4 gatos:
n <4: 2 ^ n - 1
n> = 4: C (n, 1) + C (n, 2) + C (n, 3) + C (n, 4)
A partir daqui, adotei a abordagem fácil de incrementar simples n até passar o número necessário de andares.
Código Python:
Isso fornece a solução correta para (100, 2) = 14.
Para quem deseja verificar algo menos trivial, fornece (1 000 000, 5) = 43.
Isso ocorre em O (n), onde n é a resposta para o problema (quanto mais gatos, melhor).
No entanto, tenho certeza de que alguém com um nível mais alto de matemática poderia simplificar as fórmulas por partes para calcular em O (1).
fonte
fonte
Não consigo ler o blogspot do google sobre isso (graças ao works blogwall), mas não acho que uma pesquisa direta em estilo binário seria melhor. O motivo é que uma pesquisa binária se baseia na noção de que a resposta que você está procurando tem a mesma chance de estar em qualquer índice de índice da lista. No entanto, neste caso, isso não é verdade. Nesse caso, a resposta terá uma probabilidade maior de estar mais perto de uma extremidade do intervalo do que a outra. Não tenho idéia de como levar isso em consideração na pesquisa, mas é um pensamento interessante.
fonte
toda essa conversa louca sobre gatos ... e é apenas um palpite que o problema do número com palpites mínimos (número de gatos). também não deve ser necessário definir artificialmente (e incorretamente) o infinito como parte da solução. a variável deveria ter sido chamada de limite superior ou tentativa máxima ou algo parecido. a definição do problema (a coisa do gato) tem alguns problemas sérios, com as pessoas respondendo ao potencial de crueldade animal e também as muitas facetas desse problema colocadas na vida real, por exemplo, resistência ao ar, gravidade é aceleração e outros parâmetros da vida real do problema. então talvez devesse ter sido perguntado de uma maneira totalmente diferente.
fonte