Imaginez que vous êtes dans un grand immeuble avec un chat. Le chat peut survivre à une chute d'une fenêtre à un étage bas, mais mourra s'il est jeté d'un étage élevé. Comment pouvez-vous déterminer la plus longue goutte à laquelle le chat peut survivre, en utilisant le moins de tentatives possible?
De toute évidence, si vous n'avez qu'un seul chat, vous ne pouvez rechercher que linéairement. Jetez d'abord le chat du premier étage. S'il survit, lancez-le dès le second. Finalement, après avoir été jeté du sol f, le chat mourra. Vous savez alors que l'étage f-1 était l'étage maximal de sécurité.
Mais que faire si vous avez plus d'un chat? Vous pouvez maintenant essayer une sorte de recherche logarithmique. Disons que la construction a 100 étages et que vous avez deux chats identiques. Si vous jetez le premier chat hors du 50e étage et qu'il meurt, vous n'avez qu'à fouiller 50 étages linéairement. Vous pouvez faire encore mieux si vous choisissez un étage inférieur pour votre première tentative. Disons que vous choisissez de vous attaquer au problème 20 étages à la fois et que le premier étage mortel est le # 50. Dans ce cas, votre premier chat survivra aux vols des étages 20 et 40 avant de mourir à partir du 60e étage. Il vous suffit de vérifier les étages 41 à 49 individuellement. Cela représente un total de 12 tentatives, ce qui est bien mieux que les 50 dont vous auriez besoin si vous tentiez d'utiliser l'élimination binaire.
En général, quelle est la meilleure stratégie et le pire des cas de complexité pour un bâtiment de n étages avec 2 chats? Et pour n étages et m chats?
Supposons que tous les chats sont équivalents: ils survivront tous ou mourront d'une chute d'une fenêtre donnée. De plus, chaque tentative est indépendante: si un chat survit à une chute, il est complètement indemne.
Ce ne sont pas des devoirs, même si je l'ai peut-être résolu une fois pour une affectation scolaire. C'est juste un problème fantaisiste qui m'est venu à l'esprit aujourd'hui et je ne me souviens pas de la solution. Des points bonus si quelqu'un connaît le nom de ce problème ou de l'algorithme de solution.
Réponses:
Vous pouvez facilement écrire un peu de DP (programmation dynamique) pour le cas général de n étages et m chats.
La formule principale,,
a[n][m] = min(max(a[k - 1][m - 1], a[n - k][m]) + 1) : for each k in 1..n
devrait être explicite:k - 1
étages à vérifier (tous ci-dessousk
) et desm - 1
chats (a[k - 1][m - 1]
).n - k
reste des étages (tous les étages supérieursk
) et encore desm
chats.max
.+ 1
vient du fait que nous venons d'utiliser une seule tentative (que le chat ait survécu ou non).min(f(k)) : for k in 1..n
.Il est en accord avec le résultat de Google du lien de Gaurav Saxena pour (100, 2).
Vous pouvez facilement trouver une stratégie (comment lancer le premier chat), si vous enregistrez le mieux
k
dans un autre tableau.Il existe également une solution plus rapide, n'impliquant pas de calculs O (n ^ 3), mais j'ai déjà un peu sommeil.
edit
Oh ouais, je me souviens où j'ai vu ce problème avant .
la source
+ 1
besoin d'être en dehors dumin()
? Comme vous le dites vous-même, que la tentative réussisse ou non, c'est toujours une tentative.+1
extérieur demin
. Ou le déplacer à l'intérieur demax
:)Selon un épisode récent de Radiolab (sur "Falling") , un chat atteint sa vitesse terminale au 9ème étage. Après cela, il se détend et risque moins d'être blessé. Il y a des chats complètement indemnes après une chute de dessus le 30. Les étages les plus risqués sont du 5e au 9e.
la source
La meilleure stratégie pour résoudre ce problème consiste à étudier, en utilisant la loi de la physique, la probabilité que vos hypothèses soient vraies en premier lieu.
Si vous l'aviez fait, vous vous rendriez compte que les chances de survie du chat augmentent en fait plus la distance au sol est élevée. Bien sûr, en supposant que vous le jetiez d'un bâtiment toujours plus haut, comme les tours Petronas, et non d'une montagne toujours plus haute, comme le mont Everest.
Edit:
En fait, vous verriez une distribution de chameaux inachevée.
Premièrement, la probabilité que le chat meure est faible (très basse altitude), puis elle augmente (basse altitude), puis à nouveau plus basse (altitude plus élevée), puis à nouveau plus élevée (très haute altitude).
Le graphique de la probabilité de mort d'un chat en fonction de l'altitude au-dessus du sol ressemble à ceci:
(terminer à 3, car distribution de chameaux inachevée)
Mise à jour:
la vitesse terminale d'un chat est de 100 km / h (60 mph) [= 27,7 m / s = 25,4 yards / s].
La vitesse terminale humaine est de 210 km / h (130 mph). [= 75 m / s = 68,58 yards / s]
Source de vitesse du terminal:
http://en.wikipedia.org/wiki/Cat_righting_reflex
Crédits:
Goooooogle
Je dois vérifier plus tard:
http://en.wikipedia.org/wiki/Terminal_velocity
http://www.grc.nasa.gov /WWW/K-12/airplane/termv.html
la source
J'ai d'abord lu ce problème dans le manuel de conception d'algorithmes de Steven Skiena (exercice 8.15). Il a suivi un chapitre sur la programmation dynamique, mais vous n'avez pas besoin de connaître la programmation dynamique pour prouver des limites précises sur la stratégie . D'abord l'énoncé du problème, puis la solution ci-dessous.
Seulement 1 œuf
Faire tomber l'œuf de chaque étage en commençant par le premier trouvera l'étage critique dans les n opérations (au pire).
Il n'y a pas d'algorithme plus rapide. A tout moment dans n'importe quel algorithme, laissez g le dernier étage d'où l'œuf a été vu ne pas se casser. L'algorithme doit tester le plancher g + 1 avant tout étage supérieur h> g + 1, sinon si l'œuf venait à se casser du plancher h, il ne pourrait pas faire la distinction entre f = g + 1 et f = h.
2 oeufs
Tout d'abord, considérons le cas des k = 2 œufs, lorsque n = r ** 2 est un carré parfait. Voici une stratégie qui prend O (sqrt (n)) temps. Commencez par déposer le premier œuf par incréments de r étages. Lorsque le premier œuf se brise, disons au sol
ar
, nous savons que le sol critique f doit être(a-1)r < f <= ar
. Nous déposons ensuite le deuxième œuf de chaque étage à partir de(a-1)r
. Lorsque le deuxième œuf se brise, nous avons trouvé le plancher critique. Nous avons déposé chaque œuf au plus r fois, donc cet algorithme prend au pire 2r opérations, ce qui est Θ (sqrt (n)).Lorsque n n'est pas un carré parfait, prenez r =
ceil(sqrt(n)) ∈ Θ(sqrt(n))
. L'algorithme reste Θ (sqrt (n)).Preuve que tout algorithme prend au moins sqrt (n) temps. Supposons qu'il existe un algorithme plus rapide. Considérez la séquence d'étages à partir de laquelle il laisse tomber le premier œuf (tant qu'il ne se brise pas). Comme il tombe moins que sqrt (n), il doit y avoir un intervalle d'au moins n / sqrt (n) qui est sqrt (n). Lorsque f est dans cet intervalle, l'algorithme devra l'étudier avec le deuxième œuf, et cela doit être fait étage par étage en rappelant le cas de 1 œuf. CONTRADICTION.
k œufs
L'algorithme présenté pour 2 œufs peut être facilement étendu à k œufs. Déposez chaque œuf avec des intervalles constants, qui devraient être considérés comme les puissances de la kème racine de n. Par exemple, pour n = 1000 et k = 3, recherchez des intervalles de 100 étages avec le premier œuf, 10 avec le deuxième œuf et 1 avec le dernier œuf.
De même, nous pouvons prouver qu'aucun algorithme n'est plus rapide
Θ(n**(1/k))
en induisant à partir de la preuve k = 2.Solution exacte
Nous déduisons la récurrence en optimisant l'endroit où déposer le premier œuf (plancher g), en supposant que nous connaissons des solutions optimales pour des paramètres plus petits. Si l'œuf se brise, nous avons les étages g-1 ci-dessous à explorer avec des œufs k-1. Si l'œuf survit, nous avons ng étages au-dessus à explorer avec k œufs. Le diable choisit le pire pour nous. Ainsi pour k> 1 la récurrence
la source
O(k*n**(1/k))
dans le pire des cas? Puisque dans le pire des cas, je dois traverser des momentsn**(1/k)
précisk
.Cela ne suppose-t-il pas que vous utilisez "The Same Cat"?
Vous pouvez l'aborder mathématiquement, mais c'est la bonne chose à propos des mathématiques ... avec les bonnes hypothèses, 0 peut égaler 1 (pour de grandes valeurs de 0).
D'un point de vue pratique, vous pouvez obtenir «Similar Cats», mais vous ne pouvez pas obtenir «The Same Cat».
Vous pourriez essayer de déterminer la réponse de manière empirique, mais je pense qu'il y aurait suffisamment de différences statistiques pour que la réponse soit statistiquement dénuée de sens.
Vous pourriez essayer d'utiliser "The Same Cat", mais cela ne fonctionnerait pas, car après la première goutte, ce n'est plus le même chat. (De la même manière, on ne peut jamais entrer deux fois dans la même rivière)
Ou, vous pouvez agréger la santé du chat, échantillonner à des intervalles extrêmement rapprochés, et trouver les hauteurs pour lesquelles le chat est «surtout vivant» (par opposition à «presque mort» de «The Princess Bride»). Les chats survivront, en moyenne (jusqu'au dernier intervalle).
Je pense que je me suis éloigné de l'intention initiale, mais si vous suivez la voie empirique, je vote pour commencer aussi haut que possible et continuer à laisser tomber les chats à mesure que la taille diminue jusqu'à ce qu'ils survivent statistiquement. Et puis refaites le test sur les chats survivants pour être sûr.
la source
J'ai pris une méthode légèrement différente pour produire une solution.
J'ai commencé par déterminer le plancher maximal qui pourrait être couvert en utilisant x chats et y suppositions en utilisant la méthode suivante.
Commencez avec 1 étage et continuez à augmenter le nombre de suppositions tout en gardant une trace des étages vérifiés, de la supposition sur laquelle ils ont été vérifiés et du nombre de chats restants pour chaque étage.
Répétez cette opération jusqu'à y fois.
Ce code très inefficace pour calculer la réponse donnée mais néanmoins utile pour un petit nombre de chats / étages.
Code Python:
Pour 2 chats, le nombre maximum d'étages pouvant être identifiés en x estimations est:
1, 3, 6, 10, 15, 21, 28 ...
Pour 3 chats:
1, 3, 7, 14, 25, 41, 63 ...
Pour 4 chats:
1, 3, 7, 15, 30, 56, 98 ...
Après des recherches approfondies (impliquant principalement la saisie de séquences de nombres dans OEIS ), j'ai remarqué que les étages maximums pour x suivent un modèle de combinaison par morceaux.
Pour 2 chats:
n <2: 2 ^ n - 1
n> = 2: C (n, 1) + C (n, 2)
Pour 3 chats:
n <3: 2 ^ n - 1
n> = 3: C (n, 1) + C (n, 2) + C (n, 3)
Pour 4 chats:
n <4: 2 ^ n - 1
n> = 4: C (n, 1) + C (n, 2) + C (n, 3) + C (n, 4)
À partir de là, j'ai adopté l'approche simple consistant à incrémenter simplement n jusqu'à ce que je passe le nombre d'étages requis.
Code Python:
Cela donne la bonne solution pour (100, 2) = 14.
Pour quiconque souhaite vérifier quelque chose de moins trivial, cela donne (1 000 000, 5) = 43.
Cela fonctionne en O (n) où n est la réponse au problème (plus il y a de chats, mieux c'est).
Cependant, je suis sûr qu'une personne avec un niveau plus élevé de mathématiques pourrait simplifier les formules par morceaux à calculer en O (1).
la source
la source
Je ne peux pas lire le blogspot google à ce sujet (grâce aux travaux blogwall) mais je ne pense pas qu'une recherche de style binaire simple serait la meilleure. La raison en est qu'une recherche binaire est basée sur la notion que la réponse que vous recherchez a une chance égale d'être à n'importe quel index d'index de la liste. Cependant, dans ce cas, ce n'est pas vrai. Dans ce cas, la réponse aura une probabilité plus élevée d'être plus proche d'une extrémité de la plage que de l'autre. Je ne sais pas comment intégrer cela dans la recherche, mais c'est une pensée intéressante.
la source
tout ce discours fou sur les chats ... et c'est juste une estimation du problème de nombre avec un minimum de suppositions (nombre de chats). il ne devrait pas non plus être nécessaire de définir artificiellement (et incorrectement) l'infini comme faisant partie de la solution. la variable doit avoir été nommée borne supérieure ou max-try ou quelque chose du genre. la définition du problème (le truc du chat) présente cependant de sérieux problèmes, les gens réagissant au potentiel de cruauté envers les animaux et aussi les nombreuses facettes d'un tel problème posé dans la vie réelle, par exemple la traînée d'air, la gravité est l'accélération, et d'autres paramètres de la vie réelle du problème. alors peut-être que cela aurait dû être demandé d'une manière totalement différente.
la source