Buku di Rak

12

Saya punya beberapa buku dan rak buku. Saya ingin meletakkan sebanyak mungkin buku di rak, tetapi saya memiliki peraturan. Semua dimensi buku (tinggi, lebar, dan kedalaman) harus membentuk urutan yang tidak bertambah di rak.

Ini berarti setiap buku setidaknya harus setinggi buku setelahnya sendiri. Hal yang sama berlaku untuk lebar dan kedalaman. Anda tidak dapat memutar buku untuk menukar tinggi, lebar, dan dalamnya.

Anda harus menulis program atau fungsi yang memberikan dimensi semua buku sebagai input input atau mengembalikan jumlah maksimal buku yang bisa saya letakkan di rak.

Memasukkan

  • Daftar kembar tiga bilangan bulat positif tempat setiap triplet menentukan tinggi, lebar, dan kedalaman buku.
  • Setidaknya akan ada satu triplet dalam daftar input.
  • Dua buku dapat memiliki panjang yang sama di sepanjang sejumlah dimensi.

Keluaran

  • Satu bilangan bulat positif, jumlah maksimal buku yang muat di rak mematuhi aturan.

Kompleksitas waktu

Algoritme Anda harus memiliki polinomial kompleksitas waktu terburuk dalam jumlah buku. Ini berarti bahwa misalnya kompleksitas waktu berikut semuanya valid: O (N ^ 3), O (log (N) * N ^ 2), O (N) dan yang berikut ini tidak valid: O (2 ^ N), O (N!), O (N ^ N).

Contohnya

Input => Output

(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

Ini adalah kode golf sehingga entri terpendek menang.

Tantangan penyortiran buku terkait yang menarik: Book Stack Sort .

randomra
sumber
Apakah maksud Anda harus membentuk urutan menurun? Itulah yang Anda dapatkan jika setiap buku setidaknya setinggi buku sesudahnya, kecuali setiap buku sama tingginya.
mbomb007
@ mbomb007 Benar, berubah "tidak berkurang" menjadi "tidak meningkat".
randomra

Jawaban:

4

Python 3: 436 byte

Pada awalnya saya melihat ini sebagai masalah NP-lengkap untuk menemukan jalur sederhana terpanjang dalam grafik berarah dengan siklus. Namun, setiap siklus dalam grafik (sebenarnya subgraph lengkap) dapat direpresentasikan sebagai satu simpul. Dengan kata lain, perlakukan buku-buku identik sebagai satu buku, untuk ditempatkan di rak sebagai satu unit. Kita kemudian dapat membuat grafik asiklik terarah di mana a-> b berarti b dapat mengikuti a di rak. Akhirnya, kami menemukan ketinggian maksimum pohon keluar (s) menggunakan metode rekursif.

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
sumber
1
Ini adalah solusi yang bagus, tetapi belum benar-benar bermain golf. Saya akan menang setelah itu.
isaacg
3

Pyth, 40 byte

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

Tidak cepat, tetapi jumlahnya banyak.

Setara 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
sumber
Versi Python 3 adalah 177 byte dengan golf yang jelas. Hanya sebuah fyi.
mbomb007
0

Python 2, 231 byte

Coba di sini

Program saya saat ini mendapatkan dua contoh terakhir yang salah. Bisakah seseorang membantu saya memperbaikinya? Terima kasih.

Saya mengurutkan semua daftar 6 kemungkinan permutasi dari 3 dimensi, kemudian melihat apa hubungan pemesanan terus menerus terpanjang dalam daftar, kemudian menemukan maks dari mereka.

Juga, saya tahu jika bisa bermain golf lebih banyak, tetapi saya tidak tahu apakah saya bisa menggunakannya reduceuntuk melakukan ini. Sederhananya, cara ini adalah yang termudah untuk dilakukan dalam waktu yang wajar tanpa otak saya meledak.

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
sumber