Maksimum Substring İnşaatı


18

Bu meydan okumada size iki şey aktarılır:

  1. Dize uzunluğu, N
  2. LHer biri atanmış bir nokta değerine sahip dizelerin listesi . Aktarılmayan herhangi bir dizenin nokta değeri 0

NTüm alt dize noktalarının toplamı mümkün olduğunca büyük olacak şekilde bir uzunluk dizesi oluşturmanız gerekir .

Örneğin:

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

çıktı almalı

ABCDG

Noktaları ile iki alt dizeleri için ( ABCve CDG) 5 puan arasında bir toplam sahip ve başka hiçbir yapı 5 veya daha fazla puan verebilir.

Alt dizeler bir dizede birden çok kez kullanılabilir ve üst üste gelebilir. Noktaların her zaman pozitif olacağını, alt dize uzunluklarının 1 ila Nkarakter uzunluğunda olacağını varsayabilirsiniz N > 0. Birden fazla yapı maksimumsa, bunlardan herhangi birini yazdırın.

Programınızın makul bir sürede çalışması gerekir (örneklerin her biri için bir dakikadan fazla olmamalıdır):

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

Bu bir , bu yüzden en sevdiğiniz dilde en kısa cevabınızı hazırlayın!


Tam giriş biçiminizi mi kullanmalıyız yoksa dilimiz için uygun herhangi bir giriş biçimini kullanabilir miyiz?
flawr

@flawr herhangi bir uygun girdi yöntemi iyidir (sözlük, standart, fonksiyon parametreleri)
Nathan Merrill

DEFVirgül eksik tuple
isaacg

Mükemmel bir çözümüm var, ancak son test senaryosu için çok yavaş.
isaacg

1
@isaacg Zarif bir çözümüm var, ne yazık ki bu yorum onu ​​içeremeyecek kadar küçük. (
Yapmıyorum

Yanıtlar:


1

Python 2.7, 503 Bayt

Bu özellikle golf değil, özellikle verimli; sadece kaba-kaba olan uygulanabilir dizelerin nispeten yoğun bir numaralandırmasıdır. A * ile kullanmak için kabul edilebilir bir sezgisel tarama oluşturmanın çok zor olacağını düşünmüyorum, bu muhtemelen biraz daha hızlı olacaktır. Bunu yapmak zahmet etmedim, çünkü bu yöntem tüm örnekleri dizüstü bilgisayarımdaki yaklaşık 47 saniyede çözüyor.

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

Test etmek için:

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)

açıklama

vİşlevi sadece L 'ye altdizgelerin tüm oluşumları arayarak belirli bir dizeye değerini hesaplarm dizelerden oluşturulabilen nönek ile tüm uzunluk dizelerini numaralandırır . özyinelemeli olarak kendini çağırır; ilk çağrı için . Örneğin:elm''e

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

pFonksiyonu, sadece (göre numaralandırılmış şekilde bütün olası dizileri döngüsü m) ve (belirlendiği gibi en yüksek değere sahip bir döner v).

mİşlevin, alt dizelerin değerlerine göre sıralama yaparak numaralandırmaya öncelik verdiğini unutmayın . Bu, optimallik sağlamak için gereksiz olduğu ortaya çıkıyor ve aslında verimliliği biraz engelliyor; Ben kaldırarak ~ 20 kadar bayt kaydedebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.