Опрос в Facebook: узнайте порядок, который дает максимальную сумму, выбирая ящики с номером в кольце, когда два рядом с ним уничтожены

Не нашел подобного вопроса. Это заключительный круглый вопрос Facebook:

Вам дается кольцо ящиков. Каждый ящик имеет неотрицательный номер на нем, может быть дублирован.

Напишите функцию/алгоритм, который сообщит вам порядок, в котором вы выбираете поля, которые дадут вам максимальную сумму.

Ловушка, если вы выберете поле, снимается с кольца, а также два рядом с ним (справа и слева от выбранного вами).

так что, если у меня есть кольцо {10 3 8 12}

Если я выберу 12, 8 и 10 будет уничтожен, а вы останетесь с 3.

Макс будет выбирать 8 сначала, а затем 10 или 10, затем 8.

Я попробовал повторно назначить поля своим значениям, взяв их собственное значение, а затем вычитает два из них, как стоимость.

Итак, старое кольцо {10 3 8 12}

новое кольцо {-5, -15, -7, -6}, и я выберу наивысшее.

Однако это определенно не работает, если у вас есть {10, 19, 10, 0}, вы должны взять два 10, но алгоритм будет принимать значения 19 и 0.

Помогите пожалуйста?

Скорее всего, это динамическое программирование, но я не знаю, как это сделать.

Кольцо может быть любого размера.

Ответ 1

Вот какой-то питон, который решает проблему:

def sublist(i,l):
    if i == 0:
        return l[2:-1]
    elif i == len(l)-1:
        return l[1:-2]
    else:
        return l[0:i-1] + l[i+2:]

def val(l):
    if len(l) <= 3:
        return max(l)
    else:
        return max([v+val(m) for v,m in [(l[u],sublist(u,l)) for u in range(len(l))]])

def print_indices(l):
    print("Total:",val(l))
    while l:
        vals = [v+val(m) for v,m in [(l[u],sublist(u,l)) for u in range(len(l)) if sublist(u,l)]]
        if vals:
            i = vals.index(max(vals))
        else:
            i = l.index(max(l))
        print('choice:',l[i],'index:',i,'new list:',sublist(i,l))
        l = sublist(i,l)

print_indices([10,3,8,12])
print_indices([10,19,10,0])

Вывод:

Всего: 18
выбор: 10 индекс: 0 новый список: [8]
выбор: 8 индекс: 0 новый список: []

Всего: 20
выбор: 10 индекс: 0 новый список: [10]
выбор: 10 индекс: 0 новый список: []

Без сомнения, его можно было бы немного оптимизировать. Бит ключа val(), который вычисляет общее значение данного кольца. Остальное - просто бухгалтерия.