Тип 16 № 55812 

Рекурсивные алгоритмы.Рекурсивные функции с возвращаемыми значениями
i
Алгоритм вычисления значения функции F(n), где n — натуральное число, задан следующими соотношениями:
F(n) = n, если n ≥ 2025;
F(n) = n + 3 + F(n + 3), если n < 2025.
Чему равно значение выражения F(23) − F(21)?
Решение. Приведём решение на языке Python.
def F(n):
if n >= 2025:
return n
if n < 2025:
return n + 3 + F(n + 3)
print(F(23) - F(21))
Ответ: 1338.
Приведём решение Евгения Джобса (аналитическое наблюдение).
Для выявления закономерности выражения
вычислим значения функции для чисел в диапазоне [2016; 2027].
| 2027 | 2026 | 2025 | 2024 | 2023 | 2022 | 2021 | 2020 | 2019 | 2018 | 2017 | 2016 |
| 2027 | 2026 | 2025 | 4054 | 4052 | 4050 | 6078 | 6075 | 6072 | 8099 | 8095 | 8091 |
Можно заметить, что разница между числом, кратным 3, и числом, на 2 большим, увеличивается с каждой тройкой на 2. Тогда:
Следовательно, нужно понять, какой тройкой по счету будет тройка (23, 22, 21), и умножить её номер на 2. Вычислим:

Приведём решение Евгения Джобса (аналитическое, вывод формулы).
Заметим, что рекуррентная формула накапливает значение с шагом 3. То есть получает

где значение k — максимальное целое число, для которого выполняется неравенство
Найдем значения k для 23 и 21:
откуда
и

тогда 
Следовательно, имеем дело с двумя рядами одинаковой длины:






Значит, при вычитании из f(23) значения f(21) получим набор разностей:






то есть

Приведём решение Евгения Джобса на языке Python.
Так как шаг рекурсии 3, то нет необходимости хранить все значения, достаточно хранить последние три вычисленных и обращаться к вычисленным ранее значениям по признаку остатка от деления на 3. Также разница между значениями 23 и 21 составляет 2, что означает, что списка из трех элементов точно хватит.
В списке для каждого значения будет сохраняться последнее вычисленное значение для соответствующего остатка. Таким образом, на каждой итерации будет перезаписываться элемент, который был вычислен 3 итерации назад.
f = [0]*3
for n in range(2025, 2028):
f[n % 3] = n
# перебираем значения в порядке убывания до 21
for n in range(2024, 20, -1):
f[n % 3] = n + 3 + f[n % 3]
print(f[23 % 3] - f[21 % 3])
Ответ: 1338