Другие языки программирования и технологии

Как правильно составить рекурентную формулу?)

Если можно, то киньте ссылку сайта, где подробно описано составление таких формул)
Пример задания:
У исполнителя Утроитель две команды, которым присвоены номера:
1. прибавь 1
2. умножь на 3
Первая из них увеличивает число на экране на 1, вторая – утраивает его.
Программа для Утроителя – это последовательность команд.
Сколько есть программ, которые число 1 преобразуют в число 20?
Общий принцип построения рекурсии: показать зависимость следующего члена последовательности a(n+1) от текущего члена последовательности a(n).
Формула рекурсии для вашей задачи выглядит так:
a(n+1)=(a(n)+1)*3 ==> a(n+1)=3a(n)+3
Вот хороший материал по интересующей Вас теме.
http://kufas.ru/programming50.htm
Макс Краев
Макс Краев
10 096
Лучший ответ
У исполнителя две команды, значит на каждом шаге программы возможны два варианта продолжения программы исполнителя. <Здесь какие-то дурацкие рассуждения... > Из этого следует, что число возможных программ от числа n до 20 равно 2 + число_прг (n + 1) + число_прг (n * 3), где "число_прг" это функция вычисляющая возможное число программ от своего аргумента, до 20. Следует учесть, что если n > 6, то использовать команду исполнителя "умножить на 3" уже нельзя, т. к. в результате получается число больше 20, и в этом случае имеется только один вариант программы -- последовательно увеличивать число на единицу. Попробуем реализовать данный алгоритм, к примеру, на С++:

#include <iostream>

int cc(int fn) {
    if (fn == 20) return 0;
    else if (fn > 6) return 1;
    else return 2 + cc(fn + 1) + cc(fn * 3);
}

int main() {
    std::cout << cc(1) << std::endl;
}

В результате получилось 34 вариантов программ.

Данная программа работает очень медленно, если вместо числа 20 взять большое число, например 10000. Что бы ускорить рекуррентный процесс, применяют прием "мемоизация", иначе говоря, запоминание ранее посчитанных решений. При этом скорость работы программы увеличится в десятки, а может быть и сотни раз:

#include <iostream>

int m[10001] = { 0 };

int cc(int fn) {
    if (fn != 10000 && m[fn] == 0) {
        if (fn > 333) m[fn] = 1;
        else m[fn] = 2 + cc(fn + 1) + cc(fn * 3);
    }
    return m[fn];
}

int main() {
    std::cout << cc(1) << std::endl;
}
Максим Сопрунов На самом деле все мои рассуждения оказались бредом сивой кобылы. Правильная программа будет такой:

#include <iostream>

int cc(int fn) {
    return fn * 3 > 29 ? 1 : cc(fn + 1) + cc(fn * 3);
}

int main() {
    std::cout