Задание 23 КЕГЭ: сколько программ ведёт исполнителя из A в B — как считать переходы?
Задание 23: исполнитель умеет прибавлять 1 и умножать на 2 (или похожие команды), надо узнать, сколько разных программ переводят число из A в B, возможно через обязательную промежуточную точку C. Я пытаюсь перебирать все программы и теряюсь. Есть нормальный способ?
2 ответа
Это классическая задача на динамику "число путей". Заведи массив, где ways[x] — сколько программ ведёт из A в число x. Тогда из A в B считается одним проходом.
Идея: в число x можно прийти из тех чисел, откуда есть команда в x. Если команды +1 и ×2, то в x приходят из x-1 (командой +1) и из x/2 (командой ×2, если x чётное). Значит:
A, B = 3, 20
ways = [0] * (B + 1)
ways[A] = 1
for x in range(A + 1, B + 1):
ways[x] = ways[x - 1] # пришли из x-1 командой +1
if x % 2 == 0 and x // 2 >= A:
ways[x] += ways[x // 2] # пришли из x/2 командой *2
print(ways[B])
Через обязательную точку C: считаешь отдельно число программ из A в C и из C в B, потом перемножаешь (каждую первую часть можно склеить с каждой второй).
Главное — не перебирать программы, а накапливать количество путей в массиве слева направо. Это и быстро, и без потерь.
Ключевая мысль: ways[x] = сумма ways всех чисел, ОТКУДА есть команда прямо в x. Перепиши команды задания как "кто предшественники x". Для +1 предшественник x-1, для ×2 — x/2, для +3 — x-3 и т.д. И обязательно ways[A] = 1 (в саму точку старта ведёт ровно одна "пустая" программа). Через C перемножай два независимых количества — это закон умножения для последовательных этапов.