การก่อสร้างสตริงย่อยสูงสุด


18

ในการท้าทายนี้คุณจะได้รับสองสิ่ง:

  1. ความยาวสตริง N
  2. รายการสตริงLแต่ละอันมีค่าจุดที่กำหนด สตริงใด ๆ ที่ไม่ได้ผ่านมีค่าจุดเป็น 0

คุณต้องสร้างสตริงที่มีความยาวNเพื่อให้ผลรวมของคะแนนย่อยทั้งหมดมีขนาดใหญ่ที่สุดเท่าที่จะเป็นไปได้

ตัวอย่างเช่น:

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

ควรส่งออก

ABCDG

เนื่องจากสตริงย่อยทั้งสองที่มีคะแนน ( ABCและCDG) มีทั้งหมด 5 คะแนนและไม่มีสิ่งก่อสร้างอื่นที่เป็นไปได้ที่จะให้ 5 คะแนนขึ้นไป

สตริงย่อยสามารถใช้ได้หลายครั้งในสตริงและสามารถทับซ้อนกันได้ คุณสามารถคิดว่าจุดที่จะเป็นบวกความยาวย่อยจะอยู่ระหว่าง 1 ถึงNlongs N > 0ตัวอักษรและว่า หากสิ่งปลูกสร้างหลายรายการมีขนาดใหญ่สุดให้พิมพ์หนึ่งในนั้น

โปรแกรมของคุณต้องทำงานในเวลาที่เหมาะสม (ไม่เกินหนึ่งนาทีสำหรับตัวอย่างแต่ละตัวอย่าง):

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

นี่คือเพื่อเตรียมคำตอบสั้น ๆ ในภาษาที่คุณชื่นชอบ!


เราจำเป็นต้องใช้รูปแบบการป้อนข้อมูลที่แน่นอนของคุณหรือเราสามารถใช้รูปแบบการป้อนข้อมูลที่สะดวกสำหรับภาษาของเราได้หรือไม่?
ข้อบกพร่อง

@ flawr วิธีการป้อนข้อมูลที่สะดวกใด ๆ นั้นใช้ได้ (พจนานุกรม, stdin, params function)
Nathan Merrill

DEFtuple หายไปจุลภาค
isaacg

ฉันมีทางออกที่ดีอย่างสมบูรณ์ แต่มันช้าเกินไปสำหรับกรณีทดสอบครั้งสุดท้าย
isaacg

1
@isaacg ฉันมีทางออกที่สง่างามน่าเศร้าที่ความคิดเห็นนี้มีขนาดเล็กเกินไปที่จะเก็บไว้ (ฉันไม่ต้องการเพียงแค่อ้างถึงแฟร์มาต์)
58

คำตอบ:


1

Python 2.7, 503 ไบต์

นี่ไม่ใช่การเล่นกอล์ฟโดยเฉพาะและไม่มีประสิทธิภาพโดยเฉพาะ มันเป็นเพียงการแจงนับที่ค่อนข้าง จำกัด ของสตริงที่เป็นไปได้ที่ถูกบังคับโดยสัตว์เดรัจฉาน ฉันไม่คิดว่ามันจะยากเกินไปที่จะสร้างฮิวริสติกที่ยอมรับได้เพื่อใช้กับ A * ซึ่งอาจจะเร็วขึ้นสักหน่อย แต่ฉันก็ไม่ได้สนใจที่จะทำเช่นนั้นเพราะวิธีนี้จะแก้ไขตัวอย่างทั้งหมดในเวลาประมาณ 47 วินาทีบนแล็ปท็อปของฉัน

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

เพื่อทดสอบ:

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)

คำอธิบาย

vฟังก์ชั่นเพียงคำนวณค่าของสตริงที่กำหนดโดยการค้นหาที่เกิดขึ้นทั้งหมดของสตริงในลิตรmฟังก์ชั่นระบุสตริงทั้งหมดของความยาวnที่มีคำนำหน้าว่าสามารถสร้างขึ้นจากสตริงใน e เรียกตัวเองซ้ำ ๆ ซ้ำ ๆ ; สายแรกควรผ่านในสำหรับ ตัวอย่างเช่น:lm''e

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

pฟังก์ชั่นเพียง loops ผ่านสตริงเป็นไปได้ทั้งหมด (ตามที่ระบุโดยm) และส่งกลับอย่างใดอย่างหนึ่งที่มีค่าสูงสุด (ตามที่กำหนดโดยv)

โปรดทราบว่าmฟังก์ชั่นจะจัดลำดับความสำคัญการแจงนับโดยการเรียงลำดับตามค่าของสตริงย่อย สิ่งนี้กลายเป็นสิ่งที่ไม่จำเป็นเพื่อให้แน่ใจว่ามีการปรับให้เหมาะสมและจริง ๆ แล้วมันเป็นอุปสรรคต่อประสิทธิภาพเล็กน้อย ฉันสามารถบันทึกได้ประมาณ 20 ไบต์หรือมากกว่านั้นโดยการลบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.