창문 밖으로 고양이 던지기


150

고양이가있는 고층 빌딩에 있다고 상상해보십시오. 고양이는 낮은 이야기 창에서 떨어지더라도 살아남을 수 있지만 높은 층에서 던져지면 죽을 것입니다. 가장 적은 횟수의 시도로 고양이가 생존 할 수있는 가장 긴 방울을 어떻게 알 수 있습니까?

분명히 고양이가 하나뿐이라면 선형으로 만 검색 할 수 있습니다. 먼저 1 층에서 고양이를 던져라. 살아남 으면 두 번째에서 던지십시오. 결국, 층 f에서 던져진 후, 고양이는 죽을 것이다. 그러면 층 f-1이 최대 안전 층임을 알 수 있습니다.

그러나 하나 이상의 고양이가 있다면 어떨까요? 이제 일종의 로그 검색을 시도 할 수 있습니다. 건물의 바닥이 100 개이고 고양이 두 마리가 있다고 가정 해 봅시다. 첫 번째 고양이를 50 층에서 버리고 죽으면 50 개의 층만 선형으로 검색하면됩니다. 첫 번째 시도에서 더 낮은 층을 선택하면 더 잘할 수 있습니다. 한 번에 20 층 문제를 해결하기로 선택하고 첫 번째 치명적인 층이 # 50이라고 가정 해 봅시다. 이 경우 첫 번째 고양이는 60 층에서 죽기 전에 20 층과 40 층에서 비행을 계속합니다. 41 층에서 49 층까지 개별적으로 확인하면됩니다. 그것은 총 12 번의 시도로, 이진 제거를 시도했을 때 필요한 50보다 훨씬 낫습니다.

일반적으로 가장 좋은 전략은 무엇이며 고양이 2 마리가있는 n 층 건물의 경우 최악의 복잡성입니까? n 층과 m 고양이는 어떻습니까?

모든 고양이가 동등하다고 가정하십시오. 모두 주어진 창에서 떨어지면 생존하거나 죽을 것입니다. 또한 모든 시도는 독립적입니다. 고양이가 넘어져도 완전히 무사합니다.

학교 과제로 한 번 해결했지만 숙제는 아닙니다. 그것은 오늘날 내 머리에 떠오른 기발한 문제이며 해결책을 기억하지 못합니다. 이 문제 또는 솔루션 알고리즘의 이름을 아는 사람이라면 보너스 포인트.


123
설명 된 방식으로 고양이를 사용하는 것에 반대합니다. 개로 바꿀 수 있습니까?
Thilo

53
그렇게 간단하지 않습니다. 연구는 (고양이 던져져 버리지 않고 고층 빌딩에서 떨어지는 고양이에 대한) 것입니다. 그들이 사망 한 특정 범위와 그들이 살아남은이 범위보다 *** 높은 범위가있었습니다. 그들이 어떻게 몸을 긴장시키는 지에 대한 뭔가.
앤드류 셰퍼드

5
나는 15 피트 이상인 곳에서 고양이가 생존 할 확률이 더 높다는 것을 읽었습니다. 우리가 전 여자 친구를 버리거나 아내를 잔소리하는 경우이 질문이 더 적합 할 것입니다.
Anthony Forloney

34
고양이 두 마리로 시작하면 몇 개월 만 기다렸다가 이진 검색을 실행하면됩니다. 또는 그 후 몇 개월을 기다렸다가 "동시 검색"을 수행하면 모든 층에서 동시에 고양이를 던질 수 있습니다.이 경우 살아남은 고양이의 수는 당연히 던질 수있는 가장 높은 층 수입니다. .
mjfgates 님

10
토끼와 함께 "달"을 "주"로 변경하십시오.
mjfgates 님

답변:


70

n 층과 고양이의 일반적인 경우에 대해 약간의 DP (동적 프로그래밍)를 쉽게 작성할 수 있습니다.

주요 공식 a[n][m] = min(max(a[k - 1][m - 1], a[n - k][m]) + 1) : for each k in 1..n은 설명이 필요합니다.

  • 첫 번째 고양이가 k 번째 층에서 던져져 죽으면, 우리는 k - 1(아래 모두 k)와 m - 1고양이 ( a[k - 1][m - 1]) 를 점검 할 바닥을 갖게 됩니다.
  • 고양이가 살아남 으면 n - k바닥이 남아 있고 (위의 모든 층 k) 여전히 m고양이가 있습니다.
  • 따라서 두 가지 중 최악의 경우를 선택해야합니다 max.
  • + 1 고양이가 생존했는지 여부에 관계없이 우리가 한 번의 시도를 사용했다는 사실에서 비롯됩니다.
  • 우리는 최상의 결과를 찾기 위해 가능한 모든 층을 시도합니다 min(f(k)) : for k in 1..n.

그것은 (100, 2)에 대한 Gaurav Saxena 의 링크의 Google 결과에 동의합니다 .

int n = 100; // number of floors
int m = 20; // number of cats
int INFINITY = 1000000;

int[][] a = new int[n + 1][m + 1];
for (int i = 1; i <= n; ++i) {
    // no cats - no game
    a[i][0] = INFINITY;
}

for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
        // i floors, j cats
        a[i][j] = INFINITY;

        for (int k = 1; k <= i; ++k) {
            // try throw first cat from k-th floor
            int result = Math.max(a[k - 1][j - 1], a[i - k][j]) + 1;
            a[i][j] = Math.min(a[i][j], result);
        }
    }
}

System.out.println(a[n][m]);

k다른 배열에서 가장 잘 저장하면 전략 (첫 번째 고양이를 던지는 방법)을 쉽게 찾을 수 있습니다 .

O (n ^ 3) 계산을 포함하지 않는 더 빠른 솔루션도 있지만 이미 조금 졸려 있습니다.

편집
오 예, 전에이 문제가 발생한 위치가 기억납니다 .


흠, + 1외부에있을 필요는 min()없습니까? 당신이 말했듯이, 시도의 성공 여부는 여전히 시도입니다.
j_random_hacker

@j_random_hacker 변경 사항이 있습니까? +1외부로 이동 중 min입니다. 또는 내부를 이동 max:
니키타 리박

@Nikita : 나는 당신이 쓴 것을 어떻게 든 잘못 읽게되어 유감입니다. +1.
j_random_hacker

이는 Google Code Jam의 "Egg Drop 문제"와 동일합니다. 큰 문제 세트는 N = 2000000000. 사용하기 때문에 O (N ^ 3) 아래에 충분한 용액이 아닌 code.google.com/codejam/contest/dashboard?c=32003#s=p2
ripper234

1
O (n) 알고리즘에 대해서는이 새로운 질문을 참조하십시오. Google 코드 잼에 대한 최고의 답변은 O (n)이지만 아직 이해가되지 않습니다. stackoverflow.com/questions/4699067/…
ripper234

92

에 따르면 ( "하강"에 대한) Radiolab의 최근 에피소드 , 고양이는 9 층에 의해 종단 속도에 도달합니다. 그 후, 그것은 이완되고 다칠 가능성이 적습니다. 30 일 이상 넘어져도 다 치지 않은 고양이가 있습니다. 가장 위험한 층은 5-9입니다.


16
고양이의 한 사람으로서,이 연구는 방어 사건 이후 동물 병원 보고서를 바탕으로 한 것임을 지적하고 싶습니다. 이 문의에서 다른 고양이는 다치거나 불편하지 않았습니다.
Thilo

16
답이 아니라 비즈니스 도메인의 추가 컨텍스트입니다.
Thilo

19
질문의 가치만큼 대답입니다.
Mark Ransom

2
이것은 결과로 live = 1, die = 0의 경우가 아니라 live = 1.0, die = 0.0 및 그 사이의 모든 것이 확률 인 방법을 보여줍니다. 또한 선이 아닌 곡선이므로 발견해야합니다.
tadman

73
이 보고서의 문제점은 선택 편견입니다. 아무도 죽은 고양이를 수의사에게 데려 가지 않습니다.
Niki Yoshiuchi

10

고양이가있는 고층 빌딩에 있다고 상상해보십시오. 고양이는 낮은 이야기 창에서 떨어지더라도 살아남을 수 있지만 높은 층에서 던져지면 죽을 것입니다. 가장 적은 횟수의 시도로 고양이가 생존 할 수있는 가장 긴 방울을 어떻게 알 수 있습니까?

이 문제를 해결하기위한 최선의 전략은 물리 법칙을 사용하여 가정이 처음에 사실 일 가능성을 조사하는 것입니다.

만일 그렇게한다면, 고양이의 생존 가능성은 실제로 지상까지의 거리가 멀어 질수록 증가한다는 것을 알게 될 것입니다. 물론, 페트로나스 타워와 같은 더 높은 건물에서 던지고, 에베레스트 산과 같은 더 높은 산에서 던지지 않는다고 가정하십시오.

편집하다:
실제로, 당신은 미완성 낙타 분포를 볼 수 있습니다.
첫째, 고양이가 죽을 확률은 낮고 (매우 낮은 고도), 다시 높아집니다 (낮은 고도), 다시 낮아집니다 (높은 고도), 다시 높아집니다 (매우 높은 고도).

지상에서 고도의 함수로서 고양이가 죽을 확률에 대한 그래프는 다음과 같습니다 :
(완료되지 않은 낙타 분포로 인해 3에서 끝납니다)

대체 텍스트

업데이트 :
고양이의 터미널 속도는 100km / h (60mph) [= 27.7m / s = 25.4 야드 / s]입니다.
인간 종말 속도는 210km / h (130mph)입니다. [= 75m / s = 68.58 야드 / s]

터미널 속도 소스 :
http://en.wikipedia.org/wiki/Cat_righting_reflex

크레딧 :
Goooooogle

나중에 확인해야합니다 :
http://en.wikipedia.org/wiki/Terminal_velocity
http://www.grc.nasa.gov /WWW/K-12/airplane/termv.html



2
이 올바른지? 일단 터미널 속도에 도달하면 기회는 변할 수 없으며 고양이가 터미널 속도 저하에서 살아남을 수 있다는 인상을 받았습니다.
ZoFreX

4
@ZoFreX : 물론 가능합니다. 가장 치명적인 터미널 속도 바로 아래입니다. 반면에, 수십만 마일 떨어진 곳에서 고양이를 떨어 뜨리면, 진공 상태에서 죽고 나서 사는 것보다 고양이가 대기에서 타 버릴 가능성이 높습니다.
David Thornley

1
그 그래프에 토끼 귀가 있습니까?
ninjalj

1
@ZoFreX : 각운동량. 고양이의 몸 디자인과 고양이의 회전 기술로 인해 각운동량으로 인해 고양이는 항상 발에 착륙합니다. 그러나 그것은 여전히 ​​돌릴 시간이 필요하다는 것을 의미합니다. 시간이 많을수록 (==> 고도가 높을수록) 고양이가 발에 착륙 할 가능성이 높아집니다 (==> 머리에 착륙하는 것과는 달리 생존 가능성이 급격히 증가합니다). 그러나 당신 말이 맞아, 터미널 속도에 도달 한 후에도 확률은 동일하게 유지됩니다. 나는 고양이가 터미널 속도 저하에서 살아남을 가능성이 높다고 말하고 적어도 적어도 내 창문이 긁히지 않고 욕실 창 밖으로 떨어졌습니다 (약 20m).
Stefan Steiger

8

먼저 Steven Skiena의 알고리즘 디자인 매뉴얼 (실습 8.15) 에서이 문제를 읽었습니다 . 동적 프로그래밍에 관한 장을 따랐지만 전략에 대한 정확한 한계를 입증하기 위해 동적 프로그래밍을 알 필요는 없습니다 . 먼저 문제를 진술 한 다음 아래 해결책을 찾으십시오.

계란을 충분히 높이 떨어 뜨리면 깨집니다. n 층 건물이 주어지면 바닥에서 휴식을 취한 계란이 있어야하지만 바닥에서 떨어진 계란은 살아남 아야합니다. (계란이 바닥에서 끊어지면 f = 1이라고합니다. 달걀이 바닥에서 살아남 으면 f = n + 1이라고합니다).

임계 층을 찾으려고합니다. f. 수행 할 수있는 유일한 작업은 계란을 바닥에서 떨어 뜨리고 어떻게되는지 확인하는 것입니다. 계란으로 시작하여 가능한 한 적은 계란을 떨어 뜨리려고합니다. 깨진 계란은 재사용 할 수 없습니다 (손상되지 않은 계란은 할 수 있음). E (k, n)은 항상 충분한 계란 배설물의 최소 개수가되도록하십시오.

  1. E (1, n) = n임을 보여줍니다.
  2. 보여주세요 E(k,n) = Θ(n**(1/k)).
  3. E (k, n)에 대한 재발을 찾으십시오. E (k, n)을 찾기위한 동적 프로그램의 실행 시간은 무엇입니까?

계란 1 개만

처음부터 시작하여 각 층에서 알을 떨어 뜨리면 (최악 한) n 작업에서 임계 층이 발견됩니다.

더 빠른 알고리즘이 없습니다. 알고리즘에서 언제든지 계란이 깨지지 않는 가장 높은 층을 만드십시오. 알고리즘은 더 높은 층 h> g + 1보다 먼저 층 g + 1을 테스트해야하며, 그렇지 않으면 알이 층 h에서 벗어나면 f = g + 1과 f = h를 구별 할 수 없습니다.

계란 2 개

먼저, n = r ** 2가 완벽한 제곱 일 때 k = 2 에그 사례를 고려해 봅시다. O (sqrt (n)) 시간이 걸리는 전략은 다음과 같습니다. 첫 번째 알을 r 층 단위로 떨어 뜨려 시작하십시오. 최초의 계란 나누기, 바닥에서 말할 때 ar, 우리는 중요한 바닥 f는해야합니다 알고 (a-1)r < f <= ar. 그런 다음에서 시작하여 각 층에서 두 번째 알을 떨어 뜨립니다 (a-1)r. 두 번째 알이 부러지면 중요한 바닥을 찾았습니다. 우리는 각 알을 r 시간마다 떨어 뜨렸으므로이 알고리즘은 최악의 2r 연산을 취하는데 Θ (sqrt (n))입니다.

n이 완전 제곱이 아닌 경우 r =을 사용하십시오 ceil(sqrt(n)) ∈ Θ(sqrt(n)). 알고리즘은 Θ (sqrt (n))로 유지됩니다.

모든 알고리즘이 최소 sqrt (n) 시간이 걸린다는 것을 증명합니다. 더 빠른 알고리즘이 있다고 가정하십시오. 첫 번째 알을 떨어 뜨리는 일련의 바닥을 고려하십시오 (깨지지 않는 한). 그것이 sqrt (n)보다 적으므로, 적어도 n / sqrt (n)의 간격이 sqrt (n)이어야합니다. f가이 구간에있을 때 알고리즘은 두 번째 난으로이를 조사해야하며 1-egg 사례를 층 단위로 호출해야합니다. 모순.

계란

2 개의 계란에 대해 제시된 알고리즘은 k 개의 계란으로 쉽게 확장 될 수 있습니다. 각 알을 일정한 간격으로 떨어 뜨려 k의 n의 제곱으로 취해야합니다. 예를 들어, n = 1000 및 k = 3의 경우, 첫 번째 난자가있는 100 층, 두 번째 난이있는 10, 마지막 난이있는 1의 검색 간격.

마찬가지로 Θ(n**(1/k))k = 2 증명에서 유도하여 더 빠른 알고리즘이 없음을 증명할 수 있습니다 .

정확한 솔루션

우리는 더 작은 매개 변수에 대한 최적의 솔루션을 알고 있다고 가정 할 때 첫 번째 계란 (floor g)을 떨어 뜨릴 위치를 최적화하여 재발을 추론합니다. 알이 부러지면 아래에 g-1 층이있어 k-1 알을 탐색합니다. 알이 생존하면, 우리는 k 개의 알을 가지고 탐험 할 수있는 바닥이 있습니다. 악마는 우리를 위해 최악을 선택합니다. 따라서 k> 1의 재발

E(k,n) = min(max(E(k,n-g), E(k-1,g))) minimised over g in 1..n

내가 알을 가지고 있다면 왜 O(k*n**(1/k))최악의 경우 런타임 이 아닌가? 최악의 경우 나는 n**(1/k) 정확한 k시간 을 거쳐야하기 때문에 .
Rakete1111

2

"동일한 고양이"를 사용한다고 가정하지 않습니까?

수학적으로 접근 할 수는 있지만 수학에 대한 좋은 점입니다. 올바르게 가정하면 0은 1과 같습니다 (큰 값 0).

실용적인 관점에서 '유사한 고양이'는 얻을 수 있지만 "같은 고양이"는 얻을 수 없습니다.

당신은 대답을 경험적으로 결정하려고 시도 할 수 있지만, 대답이 통계적으로 의미가 없을 정도로 충분한 통계적 차이가있을 것이라고 생각합니다.

"동일한 고양이"를 사용하려고 시도 할 수 있지만 첫 번째 드롭 후 더 이상 같은 고양이가 아니기 때문에 작동하지 않습니다. (마찬가지로, 같은 강으로 두 번 밟을 수는 없습니다)

또는 매우 가까운 간격으로 샘플링하여 고양이의 건강 상태를 집계하고 고양이가 "대부분 살아있다"( "공주 신부"에서 "대부분 죽어있는") 키를 찾을 수 있습니다. 고양이는 평균적으로 (마지막 간격까지) 생존합니다.

나는 원래의 의도에서 벗어난 것 같아요. 그러나 당신이 경험적인 길을 가고 있다면, 가능한 한 높은 출발을하고 고양이가 통계적으로 생존 할 때까지 키가 줄어듦에 따라 고양이를 계속 떨어 뜨립니다. 그런 다음 살아남은 고양이를 다시 테스트하여 확인하십시오.


0

솔루션을 생성하기 위해 약간 다른 방법을 사용했습니다.

나는 x 고양이와 y 추측을 사용하여 다룰 수있는 최대 층을 다음 방법을 사용하여 시작했습니다.

1 층부터 시작하여 층 수를 확인하면서 추측 수를 계속 늘리십시오. 층 수를 확인한 것으로 추측됩니다. 각 층에 대해 몇 마리의 고양이가 남아 있는지 확인합니다.
이것을 y 번 까지 반복하십시오 .

이것은 매우 비효율적 인 코드는 주어진 대답하지만 고양이 / 바닥의 소수에 대한 그럼에도 불구하고 도움을 계산합니다.

파이썬 코드 :

def next_step(x, guess):
  next_x = []
  for y in x:
    if y[0] == guess:
      if y[1] != 1:
        next_x.append((guess+1, y[1] - 1))
    next_x.append(y)
    if y[0] == guess:
      next_x.append((guess+1, y[1]))
  return next_x

x = [(1, TOTAL_NUM_CATS)]
current_floor = 1
while len(x) <= TOTAL_NUM_FLOORS:
  x = next_step(x, current_floor)
  current_floor += 1
  print len(x)

고양이 2 마리에 대해 x 추측으로 식별 할 수있는 최대 층은
1, 3, 6, 10, 15, 21, 28입니다.

고양이 3 마리 :
1, 3, 7, 14, 25, 41, 63 ...

고양이 4 마리 :
1, 3, 7, 15, 30, 56, 98 ...

광범위한 연구 (주로 OEIS에 숫자 시퀀스 입력과 관련됨 ) 후 x 의 최대 층이 조각 단위 조합을 따르는 것으로 나타났습니다 .

고양이 2 마리 :
n <2 : 2 ^ n-1
n> = 2 : C (n, 1) + C (n, 2)

고양이 3 마리 :
n <3 : 2 ^ n-1
n> = 3 : C (n, 1) + C (n, 2) + C (n, 3)

고양이 4 마리 :
n <4 : 2 ^ n-1
n> = 4 : C (n, 1) + C (n, 2) + C (n, 3) + C (n, 4)

여기에서 필요한 층 수를 통과 할 때까지 간단한 증분 n의 쉬운 접근 방식을 취했습니다.

파이썬 코드 :

def find_smallest(floors, eggs):
  maximum_floors = 0
  n = 0
  while maximum_floors < floors:
    maximum_floors = 0
    n += 1
    if n < eggs:
      maximum_floors = 2**n - 1
    else:
      count = 0
      for x in xrange(1, eggs+1):
        maximum_floors += combination(n, x)
  print n

이것은 (100, 2) = 14에 대한 올바른 해결책을 제공합니다.
대한 사소한 것을 확인하려는 사람에게는 (1 000, 5) = 43이됩니다.

이것은 O (n)에서 실행되는데 여기서 n은 문제에 대한 답입니다 (고양이 많을수록 좋습니다).
그러나 더 높은 수준의 수학을 가진 사람은 O (1)로 계산하기 위해 조각 별 수식을 단순화 할 수 있다고 확신합니다.


0
O(m*(n^(1/m))) algorithm.

Let 'x' be the maximum number of attempts needed.  

m = 1 => linear => x=n

m = 2:  
Let the floors be split into 'k' partitions. The first cat is thrown at the end of each partition (max 'k' times). 
When it dies, the second cat is used to go up from the beginning of this partition.   
x = k + n/k.   
Minimize x by diff wrt k and setting = 0, to get k = n^(1/2) and x = 2 * n^(1/2).

m = 3:  
x = k + 2*(y^(1/2)), where y = n/k  
diff wrt x and set = 0, to get k = n^(1/3) and x = 3 * n^(1/3)

for general m:  
x = m * n^(1/m). 

-1

나는 이것에 대한 구글 블로그 스팟을 읽을 수는 없지만 (블로그 월을 작동하기 때문에) 직선 이진 스타일 검색이 최선이라고 생각하지 않습니다. 이진 검색이 당신이 찾고있는 답변이 목록의 인덱스 색인에있을 가능성이 동일하다는 개념을 기반으로하기 때문입니다. 그러나이 경우에는 그렇지 않습니다. 이 경우 답은 범위의 한쪽 끝에 비해 다른쪽에 가까울 가능성이 높습니다. 어떻게 검색에 포함 시킬지 잘 모르겠지만 흥미로운 생각입니다.


1
나는 그 질문이 가장 최악의 경우를 요구한다고 생각하므로 모든 층이 가능한 한 분포는 관련이 없습니다.
Steve Jessop

-1

고양이에 대한이 미친 이야기. 그리고 그것은 단지 최소한의 추측 (고양이의 수)에 관한 숫자 문제 일 뿐이다. 솔루션의 일부로 인피니티를 인위적으로 (그리고 잘못) 정의 할 필요가 없어야합니다. 변수의 이름은 상한 또는 최대 시도 또는 이와 같은 이름이어야합니다. 문제 정의 (고양이)는 동물 학대 가능성에 반응하는 사람들과 실제 생활에서 제기 된 이러한 문제의 많은 측면 (예 : 에어 드래그, 중력은 가속도 및 기타 실제 매개 변수)에 심각한 문제가 있습니다. 문제의. 아마도 완전히 다른 방식으로 요청되었을 것입니다.


그러나 실제 생활 문제로 위장했을 수도 있습니다. 버전 1234에서 실패했지만 버전 42에서 작동하는 자동 테스트가 있다고 가정하십시오. 고양이는 1234에서 죽었지 만 버전 42에서는 작동합니다. 어떤 개정판에서 사망 했습니까? 예를 들어 42에서 43으로 업데이트하는 것이 빠르고 쉽지만 새 버전을 체크 아웃하고 재 구축하기가 어려운 경우, 이는 고양이 문제와 매우 유사하게 보이기 시작합니다.
mcdowella
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.