Книги на полиці


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

Це кодовий гольф, тому найкоротший запис виграє.

Пов’язаний цікавий виклик щодо сортування книг : Сортування книг .


Ви маєте на увазі, що він повинен формувати зменшувальну послідовність? Це те, що ви отримуєте, якщо кожна книга як мінімум настільки висока, ніж книга після неї, якщо тільки кожна книга не має однакової висоти.
mbomb007

@ mbomb007 Правильно, змінив "не зменшується" на "не збільшується".
випадкова

Відповіді:


4

Пітон 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)

1
Це приємне рішення, але це ще не справді гольф. Я поверну пропозицію, як тільки це буде.
isaacg

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)

Версія 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.