Статья Автор: Лебедев Дмитрий Алексеевич

КЕГЭ_23_ДП на наборе команд

Постановка задачи (в достаточно общем виде):
Есть набор команд/правил, позволяющих получать из числа x другие числа.
Необходимо подсчитать число траекторий, переводящих число A в число B
На траектории возможно наложение ограничений:
  • длина траектории
  • запреты на некоторые позиции
  • необходимость содержать заданные точки
  • и т.п.
Для решения задач, возможно применение различных подходов
  • Динамическое программирование
  • Рекурсивное программирование
  • Методы линейной алгебры для исследования графов
Далее рассмотрим несколько задач и способы их решениия

Задача поиска всех решений.
Решение возможно, только если отсутствуют циклы к графе переходов (граф ациклический).
Это возможно всегда, если "система переходов" имеет "направление" (например используются команды + и *)
Стандартная постановка
Испольниетель Калькулятор умеет выполнять команды:
  • прибавлять натуральные числа из S (например 11 и 17)
  • умножать на числа из списка P - умножение возможно если результат строго больше аргумента.
    (допускается умножение на вещественные числа с округлением до целого) Например (2 и 3)
Обозначим через t(x,y, k) - число траекторий, переводящих x  в y за k команд (k = -1 будет обозначать, что на k ограничений нет)   
Возможные задания:
  1. Найдите количество траектокторий, переводящих число X в Y (t(X,Y,-1)
  2. Для заданного X, найдите минимальное  Y, такое что  t(X,Y,-1) больше заданного N
  3. Для заданного Y, найдите максимальное X, такое что  t(X,Y,-1) больше заданного N
  4. Для заданного отрезка [A;B] найдите "оптимальную" пару X, Y из отрезка, такую, что t(X,Y, -1) больше заданного N 
    "оптимальность" может быть по значению числа траекторий (минимальная) или по длине отрезка (максимальная)
  5. Для заданного отрезка [A;B] найдите "оптимальную" пару X, Y из отрезка, такую, что t(X,Y, -1) меньше заданного N 
    "оптимальность" может быть по значению числа траекторий (максимальная) или по длине отрезка (минимальная)
Приведем конкретные задания и решения
 

Заадача 1.1 
Команды 
Прибавить 1001 или  1003 или 1007
Задание
Количество траекторий из 1 в 10_025
Способ решения 
Динамическое программирование

 


Если есть команды прибавления, то количество траектрорий может быть ограмным или не быть совсем.
Поэтому интререснее задание, при котором надо для заданного A найти минимальное B, такое что количество траекторий больше заданного N
Попробуем решить такую задачу
S = [1001 ]
P = [2]
A = 1
N = 1_000_000 
При такой формулировке использование массива для ДП становиться невозможным (до какого значения задавать список?)
или достаточно сложным (если есть хотя бы две команды прибавления, то можно оценить длину списка исходя только из этих команд)
Попробуем использовать словарь  


Решение очень неэффективно, так как проверяет много промежуточных "пустых" значений 
Это хорошо понятно, если используются только команды умножения
Например, если используются команды умножения га 2 и 3 и надо найти значение, при котором число траекторий больше 1_000_000
то ответом было бы число в районе 5*108, хотя активных значений всего около 316
Это понятно, как если взять число N = 2a*3b , то число траекторий будет \(C_{a+b}^b\)
Проблема в том, что словарь в Python нельза переберать в порядке возрастания (в отличии от C++)
Для решений задания лучше применить C++ или изменить выбор следующего b
Приведем изменения на Python
 


Способ отлично работает для команд умножения, но не подойдет для следующих параметро
Команды: +1, *2, *3
A = 




Печать