К содержанию

Подтема 6 из 6 · дополнительный урок

Когда перебор не успевает

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

Слова длины 20

Для слов длины 20 перебор уже не успевает: вариантов больше триллиона. Пятибуквенных слов из АБВГ всего 4⁵ = 1024, и перебор с проверкой 'АА' not in word даёт ответ мгновенно. Но для длины 20 вариантов 4²⁰ — больше триллиона.

Нужен способ, в котором число шагов не растёт вместе с числом слов.

Состояния

Чтобы понять, можно ли дописать букву, не нужно знать всё слово. Для запрета АА достаточно знать, заканчивается ли слово на А. Разделим допустимые слова текущей длины на две группы: a — заканчиваются на А, b — на другую букву.

При дописывании буквы новые слова на А получаются только из группы b: a_новое = b. Новые слова на другую букву — из любой группы, и последних букв три: b_новое = 3 · (a + b). Для длины 1 a = 1, b = 3.

  1. Длина 1: на А одно слово, на другую букву — 3. Дальше каждая строка получается из предыдущей.
  2. Длина 2: a = 3 — А дописываем только к словам, которые кончаются не на А (прежнее b); b = 3 · (1 + 3) = 12 — другую букву дописываем к любому слову. Всего 15.
  3. Длина 3: a = 12 — А дописываем только к словам, которые кончаются не на А (прежнее b); b = 3 · (3 + 12) = 45 — другую букву дописываем к любому слову. Всего 57.
  4. Длина 4: a = 45 — А дописываем только к словам, которые кончаются не на А (прежнее b); b = 3 · (12 + 45) = 171 — другую букву дописываем к любому слову. Всего 216.
  5. Длина 5: a = 171 — А дописываем только к словам, которые кончаются не на А (прежнее b); b = 3 · (45 + 171) = 648 — другую букву дописываем к любому слову. Всего 819.

Для длины 5 получаем 171 + 648 = 819 — столько же даёт перебор. Для длины 20 меняется одно число в range:

end_a = 1end_other = 3for length in range(2, 21):    new_a = end_other    new_other = 3 * (end_a + end_other)    end_a = new_a    end_other = new_other print(end_a + end_other)
393620574951

Девятнадцать шагов вместо триллиона слов. Такой подход называют динамическим программированием: результаты для коротких слов используются для длинных.

Схемы типов

Если важны только типы цифр, перебирают схемы типов, а не сами цифры. Посчитаем двенадцатизначные восьмеричные числа, в записи которых ровно четыре нечётные цифры и никакие две нечётные не стоят рядом. Самих чисел около 6 · 10¹⁰ — перебор не успеет.

Схема — на каждом месте «ч» или «н», их всего 2¹² = 4096. Для подходящей схемы число чисел даёт умножение: нечётная цифра — 4 варианта, чётная — 4, но на первом месте чётная не может быть нулём — 3.

from itertools import product def by_types(length, odd_count):    total = 0    for types in product('чн', repeat=length):        scheme = ''.join(types)        if scheme.count('н') != odd_count:            continue        if 'нн' in scheme:            continue        ways = 1        for i, kind in enumerate(scheme):            if kind == 'н':                ways *= 4            elif i == 0:                ways *= 3            else:                ways *= 4        total += ways    return total brute = 0for d in product(range(8), repeat=5):    odd = [x % 2 for x in d]    if d[0] != 0 and sum(odd) == 2:        if all(odd[i] + odd[i + 1] < 2 for i in range(4)):            brute += 1 print(by_types(5, 2), brute)print(by_types(12, 4))
5376 5376 1820327936

Сначала способ проверен на пятизначных числах, где перебор ещё возможен, затем та же by_types считает двенадцатизначные.

Итого

  • Оценкаmⁿ вариантов; от миллиардов — не успеть
  • Состоянияхранить количества по тому, что нужно для продолжения
  • Схемы типовперебрать схемы, каждую посчитать умножением
  • Проверкасверить способ с перебором на малых длинах

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
Сколько вариантов переберёт product для слов длины 20 из четырёх букв?
ОтветСкрыть ответ
Ответ
4²⁰ — больше триллиона: перебор не успеет.
Вопрос 2
Что нужно знать о слове, чтобы понять, можно ли дописать А при запрете АА?
ОтветСкрыть ответ
Ответ
Только одно: заканчивается ли слово на А.
Вопрос 3
Слов длины 1 из АБВГ: на А — 1, на другую букву — 3. Сколько слов длины 2 без АА?
ОтветСкрыть ответ
Ответ
15: на А — 3, на другую — 3 · (1 + 3) = 12. Проверка: 16 − 1.
Вопрос 4
Сколько схем «чётная / нечётная» у двенадцатизначного числа?
ОтветСкрыть ответ
Ответ
2¹² = 4096 — их перебрать легко, а самих чисел десятки миллиардов.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Без двух А подряд, длина 6

Сколько шестибуквенных слов из АБВГ не содержит двух букв А подряд? Найди подсчётом по состояниям и проверь перебором.

Введите число.

Без двух Б подряд, длина 30

Сколько тридцатибуквенных слов из АБВ не содержит двух букв Б подряд?

Введите число.

Двадцать троичных цифр без двух нулей

Сколько существует двадцатизначных троичных чисел, в записи которых нет двух нулей подряд?

Введите число.

Три чётные цифры не рядом

Сколько существует 10-значных девятеричных чисел, в записи которых ровно три чётные цифры и никакие две чётные не стоят рядом?

Введите число.

Два нуля и не более трёх букв

Сколько существует 9-значных 15-ричных чисел, в записи которых ровно два нуля и не более трёх цифр, обозначаемых буквами?

Введите число.