Максимальное построение подстроки


18

В этом соревновании вам передаются две вещи:

  1. Длина строки, N
  2. Список строк, Lкаждая с назначенным значением точки. Любая строка, которая не передана, имеет значение 0

Вам нужно построить строку длины Nтак, чтобы сумма всех точек подстроки была как можно большей.

Например:

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

должен выводить

ABCDG

Потому что две подстроки с точками ( ABCи CDG) имеют в общей сложности 5 баллов, и никакая другая возможная конструкция не может дать 5 или более баллов.

Подстроки могут использоваться в строке несколько раз и могут перекрываться. Вы можете предположить, что точки всегда будут положительными, длина подстроки будет от 1 до длин Nсимволов, и это 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 24.12.15

@ Flawr любой удобный способ ввода в порядке (словарь, стандартный ввод, параметры функции)
Натан Меррилл

DEFКортеж отсутствует запятая
isaacg

У меня есть отличное решение, но оно слишком медленное для последнего теста.
Исаак

1
@isaacg У меня есть элегантное решение, к сожалению, этот комментарий слишком мал, чтобы его содержать. (Не хочу, просто хотел бы процитировать Ферма.)
orlp

Ответы:


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Функция просто вычисляет значение заданной строки путем поиска всех вхождений подстрок в L. mфункция перечисляет все строки длины nс префиксом , eкоторый может быть получен из подстрок в l. mрекурсивно называет себя; первый вызов должен пройти в ''течение e. Например:

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

pФункция просто перебирает все возможные строки (как нумеруются m) и возвращает один с наибольшим значением (как определено v).

Обратите внимание, что mфункция фактически устанавливает приоритеты перечисления путем сортировки на основе значений подстрок. Это оказывается ненужным для обеспечения оптимальности и фактически немного снижает эффективность; Я мог бы сохранить ~ 20 или около того байтов, удалив его.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.