Правильное и оптимальное решение - 13, 25, 36, 46, 55, 64, 72, 79, 85, 90, 94, 97, 99, 100
, в котором среднее число попыток определения пола, на котором разбиваются яйца, минимально, при условии, что пол, на котором разбиваются яйца, выбирается случайным образом.
Основываясь на этой информации, мы можем написать рекурсивную функцию, чтобы минимизировать средние испытания, которая дает решение
13, 25, 36, 46, 55, 64, 72, 79, 85, 90, 94, 97, 99, 100
Он имеет следующие максимальные испытания для каждого шага этажа
13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14
Это, очевидно, намного лучше, чем наивное решение, полученное при допущении пробелов, начинающихся с 14 и уменьшающихся. В этом случае 55% времени вам просто нужно 13 испытаний. Это очень близко к оптимальному решению, полученному из n (n+1) / 2 >= 100
, что дает n = 13.651
, и наше оптимальное решение равно (13*5+14*9)/14
, т.е. 13.643
Вот быстрая реализация:
import sys
def get_max_trials(floors):
pf = 0
trials = []
for i, f in enumerate(floors):
trials.append(i+f-pf)
pf = f
return trials
def get_trials_per_floor(floors):
# return list of trials if egg is assumed at each floor
pf = 0
trials = []
for i, f in enumerate(floors):
for mid_f in range(pf+1,f+1):
trial = (i+1) + f - mid_f + 1
if mid_f == pf+1:
trial -= 1
trials.append(trial)
pf = f
return trials
def get_average(floors):
trials = get_trials_per_floor(floors)
score = sum(trials)
return score*1.0/floors[-1], max(trials)
floors_map = {}
def get_floors(N, level=0):
if N == 1:
return [1]
if N in floors_map:
return floors_map[N]
best_floors = None
best_score = None
for i in range(1,N):
base_floors = [f+i for f in get_floors(N-i, level+1)]
for floors in [base_floors, [i] + base_floors]:
score = get_average(floors)
if best_score is None or score < best_score:
best_score = score
best_floors = floors
if N not in floors_map:
floors_map[N] = best_floors
return best_floors
floors = get_floors(100)
print "Solution:",floors
print "max trials",get_max_trials(floors)
print "avg.",get_average(floors)
naive_floors = [14, 27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100]
print "naive_solution",naive_floors
print "max trials",get_max_trials(naive_floors)
print "avg.",get_average(naive_floors)
Выход:
Solution: [13, 25, 36, 46, 55, 64, 72, 79, 85, 90, 94, 97, 99, 100]
max trials [13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14]
avg. (10.31, 14)
naive_solution [14, 27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100]
max trials [14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12]
avg. (10.35, 14)