Тема 23. Оператор присваивания и ветвления

23.05 Количество программ из A в B смешанное

Вспоминай формулы по каждой теме
Решай новые задачи каждый день
Вдумчиво разбирай решения
ШКОЛКОВО.
Готовиться с нами - ЛЕГКО!
Подтемы раздела оператор присваивания и ветвления
Решаем задачу:

Ошибка.
Попробуйте повторить позже

Задача 1#11535

Исполнитель ИВ преобразует число на экране.

У исполнителя есть три команды, которым присвоены номера:

1  . Прибавить 1

2  . Умножить на 2

3  . Прибавить 5

Первая команда увеличивает число на экране на 1  , вторая умножает его на 2  , третья увеличивает на 5  .

Программа для исполнителя ИВ — это последовательность команд.

Сколько существует программ, которые преобразуют исходное число 1  в число 16  , и при этом траектория вычислений содержит число 8  и не содержит числа 10  ?

Показать ответ и решение

Решение динамикой

Мы используем динамическое программирование, чтобы посчитать количество программ, которые приводят число 1 к числу 16, учитывая ограничения на числа 8 и 10. Идея заключается в том, чтобы создать массив, где индекс i  соответствует числу на экране, а значение в ячейке — количество способов добраться до этого числа, используя команды.

1. Создаем массив a из 17 элементов (от 0 до 16) и заполняем нулями.

2. Инициализируем начальное положение: a[1] = 1, так как мы стартуем с числа 1, существует один способ быть в этом состоянии.

3. Проходим по всем числам i  от 2 до 16:

- Сначала добавляем количество способов прийти из i− 1  командой «прибавить 1» (a[i] = a[i-1]).

- Если i > 5  , добавляем количество способов из i− 5  командой «прибавить 5» (a[i] += a[i-5]).

- Если i  четное, добавляем количество способов из i∕∕2  командой «умножить на 2» (a[i] += a[i//2]).

- Если i == 10  , обнуляем ячейку a[i] = 0, так как число 10 запрещено.

- Если i == 8  , обнуляем все ячейки перед 8 (for j in range(8): a[j] = 0), чтобы гарантировать, что траектория обязательно содержит число 8.

После прохода по всем числам, a[16] содержит количество программ, соответствующих условию задачи.

# Создаем массив для чисел от 0 до 16
a = [0]*17
# Начальное положение: число 1
a[1] = 1
# Проходим по всем числам от 2 до 16
for i in range(2, 17):
    # Добавляем количество способов прийти из i-1 командой "+1"
    a[i] = a[i-1]
    # Добавляем количество способов прийти из i-5 командой "+5", если i>5
    if i > 5:
        a[i] += a[i-5]
    # Добавляем количество способов прийти из i//2 командой "*2" для четных i
    if i % 2 == 0:
        a[i] += a[i//2]
    # Обнуляем ячейку, если i == 10, так как число 10 запрещено
    if i == 10:
        a[i] = 0
    # Если i == 8, обнуляем все предыдущие ячейки, чтобы гарантировать проход через 8
    if i == 8:
        for j in range(8):
            a[j] = 0
# Выводим количество программ, которые преобразуют 1 в 16
print(a[16])

Решение рекурсией

Мы также можем решить задачу рекурсивно. Для этого определяем функцию f(x, y), которая считает количество программ, преобразующих число x  в число y  , соблюдая условия:

1. Если x > y  или x ==  10  , возвращаем 0, так как путь невозможен или число запрещено.

2. Если x == y  , возвращаем 1, так как найден корректный путь.

3. В противном случае функция рекурсивно вызывает себя для всех трех команд:

- f(x+1, y) — добавление 1

- f(x*2, y) — умножение на 2

- f(x+5, y) — добавление 5

Так как траектория должна проходить через число 8, мы делим задачу на два этапа: от 1 до 8 и от 8 до 16. Итоговое количество программ равно произведению результатов двух этапов: f(1,8) * f(8,16).

# Определяем рекурсивную функцию f(x, y)
def f(x, y):
    # Если текущее число больше цели или равно запрещенному числу 10
    if x > y or x == 10:
        return 0
    # Если достигли цели, путь корректен
    if x == y:
        return 1
    # Суммируем количество программ для всех трех команд
    return f(x + 1, y) + f(x + 5, y) + f(x * 2, y)

# Вычисляем количество программ, проходящих через 8
print(f(1, 8) * f(8, 16))

Ответ: 45

Специальные программы

Все специальные программы

Программа
лояльности v2.0

Приглашай друзей в Школково и получай вознаграждение до 10%!

Крути рулетку
и выигрывай призы!

Крути рулетку и покупай курсы со скидкой, которая привязывается к вашему аккаунту.

Бесплатное онлайн-обучение

Для школьников из приграничных территорий России, проживающих в ДНР, ЛНР, Херсонской, Запорожской, Белгородской, Курской, Брянской областях и Крыму.

Налоговые вычеты

Узнай, как получить налоговый вычет при оплате обучения в «Школково».

Специальное предложение
для учителей

Бесплатный доступ к любому курсу подготовки к ЕГЭ, ОГЭ и олимпиадам от «Школково». Мы с вами делаем общее и важное дело, а потому для нас очень значимо быть чем-то полезными для учителей по всей России!

Вернём деньги за курс
за твою сотку на ЕГЭ

Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!

cyberpunkMouse
cyberpunkMouse
Рулетка
Вы можете получить скидку в рулетке!