Книги на полке

12

У меня есть несколько книг и книжная полка. Я хотел бы положить на полку как можно больше книг, но у меня есть правило. Все размеры книг (высота, ширина и глубина) должны образовывать не увеличивающуюся последовательность на полке.

Это означает, что каждая книга должна быть по крайней мере такой же высокой, как и те, которые стоят за ней. То же самое касается ширины и глубины. Вы не можете вращать книги, чтобы поменять местами их высоту, ширину и глубину.

Вы должны написать программу или функцию, которая дает размеры всех книг в качестве входных данных или возвращает максимальное количество книг, которое я могу положить на полку.

вход

  • Список триплетов натуральных чисел, где каждый триплет определяет высоту, ширину и глубину книги.
  • В списке входов будет хотя бы один триплет.
  • Две книги могут иметь одинаковую длину по любому количеству измерений.

Выход

  • Одно положительное целое число, максимальное количество книг, которые помещаются на полке, подчиняясь правилу.

Сложность времени

Ваш алгоритм должен иметь полиномиальную сложность времени в худшем случае по количеству книг. Это означает, что, например, допустимы следующие временные сложности: O (N ^ 3), O (log (N) * N ^ 2), O (N) и следующие недопустимые: O (2 ^ N), O (N!), O (N ^ N).

Примеры

Вход => Выход

(1, 1, 1) =>  1

(5, 2, 5), (1, 3, 5) =>  1

(5, 2, 5), (1, 2, 5) =>  2

(2, 2, 2), (2, 2, 2), (2, 2, 2), (1, 3, 6) =>  3

(1, 2, 5), (1, 3, 5), (1, 2, 8), (1, 2, 5), (7, 7, 7) =>  4

(5, 19, 3), (9, 4, 16), (15, 16, 13), (7, 4, 16), (1, 13, 14), (20, 1, 15), (9, 8, 19), (4, 11, 1) =>  3

(1, 1, 18), (1, 13, 7), (14, 1, 17), (8, 15, 16), (18, 8, 12), (8, 8, 15), (10, 1, 14), (18, 4, 6), (10, 4, 11), (17, 14, 17), (7, 10, 10), (19, 16, 17), (13, 19, 2), (16, 8, 13), (14, 6, 12), (18, 12, 3) =>  5

Это код гольф, поэтому выигрывает самый короткий вход.

Связанная интересная задача сортировки книг: Book Stack Sort .

randomra
источник
Вы подразумеваете, что это должно сформировать уменьшающуюся последовательность? Это то, что вы получите, если каждая книга будет по крайней мере такой же высокой, как и книга после нее, если только каждая книга не имеет одинаковую высоту.
mbomb007
@ mbomb007 Правильно, изменено «неубывающий» на «не возрастающий».
рандома

Ответы:

4

Python 3: 436 байт

Сначала я рассматривал это как NP-полную задачу поиска самого длинного простого пути в ориентированном графе с циклами. Тем не менее, каждый цикл в графе (фактически полный подграф) может быть представлен как одна вершина. Другими словами, относитесь к идентичным книгам как к одной книге, чтобы поместить ее на полку как единое целое. Затем мы можем построить ориентированный ациклический граф, где a-> b означает, что b может следовать за a на полке. Наконец, мы находим максимальную высоту дерева (ов), используя рекурсивный метод.

import sys
b=[]
n={}
r=[]
for L in sys.stdin.readlines():z=[int(x)for x in L.split()];r+=[z];z in b or b+=[z]
def l(a,b):return a[0]<=b[0]and a[1]<=b[1]and a[2]<=b[2]
R=range(len(b))
for i in R: 
    n[i]=[]
    for j in R:i!=j and l(b[i],b[j])and n[i]+=[j]
def L(t):
    global v;best=0
    if t in v:
            return v[t]
    for s in n[t]:best=max(best,L(s)+1)
    v[t]=best+r.count(b[t])-1;return best
m=0
for i in R:v={};m=max(L(i)+1,m)
print(m)
kbitikofer
источник
1
Это хорошее решение, но оно пока не очень удачное. Я буду голосовать, как только это будет.
Исаак
3

Pyth, 40 байт

KYleolNe.eaK+e+]])olNf.A.eg@YbZeT<Kk]YSQ

Не быстро, но полиномиально.

Эквивалент Python3:

def num_books(l):
    l = sorted(l)
    s = []
    for i, Y in enumerate(l):
        s.append(max([T for T in s[:i]
                      if all(Y[e] >= t for e, t in enumerate(T[-1]))] + [[]],
                     key=len) + [Y])
    return max(len(u) for u in s)
orlp
источник
Версия Python 3 составляет 177 байт с очевидными гольфами. Просто к вашему сведению.
mbomb007
0

Python 2, 231 байт

Попробуй здесь

Моя программа в настоящее время неправильно использует последние два примера. Может кто-нибудь помочь мне исправить это, пожалуйста? Благодарю.

Я сортирую список всех 6 возможных порядков перестановки в трех измерениях, затем вижу, какое самое длинное отношение непрерывного порядка находится в списке, а затем нахожу максимум из них.

Кроме того, я знаю, можно ли играть в гольф намного больше, но я не мог понять, смогу ли я использовать reduceдля этого. Проще говоря, этот способ проще всего сделать за разумное время без взрыва моего мозга.

from operator import*
from itertools import*
def f(t):
    m=1
    for l in(sorted(t,key=itemgetter(*o))for o in permutations(range(3))):
        c=1
        for k in range(len(l)-1):
            c+=all(i<=j for i,j in zip(l[k],l[k+1]))
        m=max(m,c)
    print m
mbomb007
источник