Konstruksi Substring Maksimal

18

Dalam tantangan ini, Anda melewati dua hal:

  1. Panjang tali, N
  2. Daftar string L,, masing-masing dengan nilai poin yang ditetapkan. Setiap string yang tidak diteruskan memiliki nilai titik 0

Anda perlu membuat string panjang Nsehingga jumlah semua titik substring adalah sebesar mungkin.

Sebagai contoh:

5 [("ABC", 3), ("DEF", 4), ("CDG", 2)]

harus keluar

ABCDG

Karena dua substring dengan poin ( ABCdan CDG) memiliki total 5 poin, dan tidak ada konstruksi lain yang mungkin dapat memberikan 5 atau lebih poin.

Substring dapat digunakan beberapa kali dalam sebuah string, dan dapat tumpang tindih. Anda dapat mengasumsikan bahwa poin akan selalu positif, panjang substring akan antara 1 hingga Nkarakter, dan itu N > 0. Jika beberapa konstruksi maksimal, cetak salah satunya.

Program Anda harus berjalan dalam jumlah waktu yang wajar (tidak lebih dari satu menit untuk masing-masing contoh):

1 [("A", 7), ("B", 4), ("C", 100)]     => C
2 [("A", 2), ("B", 3), ("AB", 2)]      => AB
2 [("A", 1), ("B", 2), ("CD", 3)]      => BB
2 [("AD", 1), ("B", 2), ("ZB", 3)]     => ZB
3 [("AB", 2), ("BC", 1), ("CA", 3)]    => CAB
3 [("ABC", 4), ("DEF", 4), ("E", 1)]   => DEF
4 [("A", 1), ("BAB", 2), ("ABCD", 3)]  => AAAA or ABAB or BABA or ABCD
5 [("A", 1), ("BAB", 2), ("ABCD", 3)]  => BABCD or BABAB
5 [("ABC", 3), ("DEF", 4), ("CDG", 2)] => ABCDG
5 [("AB", 10), ("BC", 2), ("CA", 2)]   => ABCAB
6 [("AB", 10), ("BC", 2), ("CA", 2)]   => ABABAB
8 [("AA", 3), ("BA", 5)]               => BAAAAAAA
10 [("ABCDE", 19), ("ACEBD",  18), ("ABEDC", 17), ("BCEDA", 16), ("EBDAC", 15), ("BACD", 14), ("CADB", 13), ("ABDC", 12), ("CABD", 11), ("EBDC", 10), ("ACE", 9), ("CBA", 8), ("AEC", 7), ("BE", 6), ("AE", 5), ("DC", 4), ("BA", 3), ("A", 2), ("D", 1)]
=> ACEBDACEBD

Ini adalah , jadi siapkan jawaban terpendek Anda dalam bahasa favorit Anda!

Nathan Merrill
sumber
Apakah kita harus menggunakan format input persis Anda atau dapatkah kita menggunakan format input yang mudah untuk bahasa kita?
flawr
@ flawr, metode input yang mudah apa pun baik-baik saja (kamus, stdin, params fungsi)
Nathan Merrill
The DEFtupel hilang koma
isaacg
Saya punya solusi yang sangat bagus, tetapi terlalu lambat untuk test case terakhir.
isaacg
1
@isaacg Saya punya solusi yang elegan, sayangnya komentar ini terlalu kecil untuk menampungnya. (Saya tidak, hanya ingin mengutip Fermat.)
orlp

Jawaban:

1

Python 2.7, 503 Bytes

Ini bukan golf, juga tidak efisien; itu hanya enumerasi relatif layak string yang kasar. Saya tidak berpikir itu akan terlalu sulit untuk membuat heuristik yang dapat diterima untuk digunakan dengan A *, yang mungkin akan sedikit lebih cepat. Saya tidak repot melakukan itu, karena metode ini memecahkan semua contoh dalam waktu sekitar 47 detik di laptop saya.

import re
v=lambda l,s:sum([len([m.start() for m in re.finditer('(?=%s)'%u,s)])*v for u,v in l])
def m(n,l,e):
 if len(e)==n:
  yield e
 else:
  u=1
  for s,v in sorted(l,key=lambda j:j[1],reverse=True):
   for i in range(len(s)-1,0,-1):
    if len(e)+len(s)-i <= n and e.endswith(s[:i]):
     for r in m(n,l,e+s[i:]):
      u=0;yield r
   if len(e)+len(s)<=n:
    for r in m(n,l,e+s):
     u=0;yield r
  if u:
   yield e
def p(n,l):
 b,r=-1,0
 for s in m(n,l,''):
  a=v(l,s)
  if a>b:b,r=a,s
 return r

Untuk mengujinya:

if __name__ == "__main__":
    for n, l in [
            (1, [("A", 7), ("B", 4), ("C", 100)]),     # => C
            (2, [("A", 2), ("B", 3), ("AB", 2)]),      # => AB
            (2, [("A", 1), ("B", 2), ("CD", 3)]),      # => BB
            (2, [("AD", 1), ("B", 2), ("ZB", 3)]),     # => ZB
            (3, [("AB", 2), ("BC", 1), ("CA", 3)]),    # => CAB
            (3, [("ABC", 4), ("DEF", 4), ("E", 1)]),   # => DEF
            (4, [("A", 1), ("BAB", 2), ("ABCD", 3)]),  # => AAAA or ABAB or BABA or ABCD
            (5, [("A", 1), ("BAB", 2), ("ABCD", 3)]),  # => BABCD or BABAB
            (5, [("ABC", 3), ("DEF", 4), ("CDG", 2)]), # => ABCDG
            (5, [("AB", 10), ("BC", 2), ("CA", 2)]),   # => ABCAB
            (6, [("AB", 10), ("BC", 2), ("CA", 2)]),   # => ABABAB
            (8, [("AA", 3), ("BA", 5)]),               # => BAAAAAAA
            (10, [("ABCDE", 19), ("ACEBD",  18), ("ABEDC", 17), ("BCEDA", 16), ("EBDAC", 15), ("BACD", 14), ("CADB", 13), ("ABDC", 12), ("CABD", 11), ("EBDC", 10), ("ACE", 9), ("CBA", 8), ("AEC", 7), ("BE", 6), ("AE", 5), ("DC", 4), ("BA", 3), ("A", 2), ("D", 1)]) # => ACEBDACEBD
    ]:
        print p(n, l)

Penjelasan

The vFungsi hanya menghitung nilai dari suatu string dengan mencari semua kejadian dari substring di L. mFungsi menyebutkan semua string panjang ndengan awalan eyang dapat dihasilkan dari substring di l. msecara rekursif menyebut dirinya sendiri; panggilan pertama harus lulus dalam ''untuk e. Sebagai contoh:

>>> for s in m(4, [("A", 1), ("BAB", 2), ("ABCD", 3)], ''):print s
ABCD
BABA
ABCD
ABAB
AAAA

The pFungsi hanya loop melalui semua string yang mungkin (seperti yang disebutkan oleh m) dan mengembalikan satu dengan nilai tertinggi (sebagaimana ditentukan oleh v).

Perhatikan bahwa mfungsi sebenarnya memprioritaskan pencacahan dengan mengurutkan berdasarkan nilai substring. Ini ternyata tidak perlu untuk memastikan optimalitas, dan itu sebenarnya menghambat efisiensi sedikit; Saya bisa menyimpan ~ 20 atau lebih byte dengan menghapusnya.

ESultanik
sumber