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

Для программистов слово рекурсия хорошо известно. Знают его и математики, которым больше нравится использовать слово рекуррентный. В английской терминологии часто употребляют термин –
Recursive Sequence (рекуррентная последовательность). Если вы не знаете, что такое рекурсия и рекуррентные формулы, то скорее всего этот материал вам и не стоит читать. Мы же покажем здесь, как можно используя наш калькулятор проводить рекурсивные и рекуррентные вычисления.

Начнем конечно же с числе Фибоначчи. Формула для рекурентного вычисления чисел Фибоначчи:

[F_{n}=begin{cases}0 & n = 0\1 & n = 1 \F_{n-1}+F_{n-1} & n geq 2end{cases}]

Для того, чтобы провести вычисление чисел Фибаначчи вам следует ввести в наш калькулятор команду:

f(n)=f(n-1)+f(n-2)

Следующий пример – конечно же формула рекурсивного вычисления факториала:

$$n!=(n-1) cdot n$$

Команда для калькулятора будет иметь вид:

f(n)=f(n-1)*n

Похожие публикации

2016-04-10 • Просмотров [ 59446 ]


Линейной рекуррентной последовательностью (возвратной последовательностью, линейной рекуррентой) называется всякая числовая последовательность x_{0},x_{1},dots, задаваемая линейным рекуррентным соотношением:

x_{n}=a_{1}cdot x_{n-1}+dots +a_{d}cdot x_{n-d} для всех ngeqslant d

с заданными начальными членами x_{0},dots ,x_{d-1}, где d — фиксированное натуральное число, называемое порядком последовательности, a_{1},dots ,a_{d} — заданные числовые коэффициенты, a_{d}neq 0.

Примеры известных линейных рекуррентных последовательностей можно посмотреть под калькулятором.

PLANETCALC, Линейная рекуррентная последовательность

Линейная рекуррентная последовательность

Размер последовательности для расчета

Начальные члены

Файл очень большой, при загрузке и создании может наблюдаться торможение браузера.

Точность вычисления

Знаков после запятой: 2

Примеры линейных рекуррентных последовательностей

Начнем с того, что такие известные понятия, как арифметическая прогрессия и геометрическая прогрессия, можно описать как линейные рекуррентные последовательности.

Арифметическую прогрессию с первым членом a₁ и разностью прогрессии d можно представить как линейное рекуррентное соотношение второго порядка следующего вида:
x_n = 2x_{n-1} - x_{n-2}
с x₁ = a₁ и x₂ = a₁+d соответственно. Вот так это выглядит для a₁ = 1 и d = 2.

Геометрическую прогрессию с первым членом a₁ и знаменателем прогрессии q можно представить как линейное рекуррентное соотношение первого порядка вида:
x_n = qx_{n-1}
c x₁ = a₁. Вот как это выглядит для геометрической прогрессии со знаменателем 2.

Одной из самых известных линейных рекуррентных последовательностей являются числа Фибоначчи – это последовательность, в которой первые два числа равны 0 и 1, а каждое последующее число равно сумме двух предыдущих чисел. Соотношение двух последовательных чисел Фибоначчи дает, между прочим, приближение золотого сечения.

Числа Фибоначчи относятся к последовательностям Люка – семейству пар линейных рекуррентных последовательностей второго порядка, впервые рассмотренных Эдуардом Люка. К ним же относятся и числа Люка – последовательность, в которой, как и в числах Фибоначчи, каждое последующее число равно сумме двух предыдущих чисел, но с первыми членами 2 и 1 соответственно. Числа Люка могут использоваться для проверки на простоту.

Еще две примечательные последовательности Люка это числа Пелля, с формулой
x_n=2x_{n-1}+x_{n-2}
и начальными членами 0 и 1, и числа Пелля-Люка или сопутствующие числа Пелля, с той же формулой и начальными членами 2 и 2. Примечательны эти числа тем, что с их помощью можно построить бесконечную последовательность подходящих дробей для квадратного корня из двух:
frac{1}{1},frac{3}{2},frac{7}{5},frac{17}{12},frac{41}{29},dots,
Здесь в числителе половина числа Пелля-Люка (2, 6, 14, 34, …), а в знаменателе – число Пелля (1, 2, 5, 12, …), начиная со второго числа в последовательности (n=1). Помимо этого соотношение двух последовательных чисел Пелля дает приближение так называемого серебрянного сечения.

И наконец числа трибоначчи, параметры калькулятора по умолчанию, это последовательность целых чисел, где каждое последующее число является суммой трех предыдущих, с начальными членами 0, 0, и 1. Название образовано по аналогии с “Фибоначчи” с заменой на приставку “три”, от латинского tri.

Since mathematics is a vast world, there are many functions
available to solve the mathematical problem. However, sometimes, we
can also use these functions to determine the real-world
application. Among them, one mathematical function is recursion.

Before moving on, how to use a recursive function and to know
about a tool which is known as a Recursive Formula Calculator,
first, we will go through the What is Recursive function?

Basically, in mathematics, this function is a type of service or
method or expression which consists of a concept of one or more
variables with their characteristics, which is specified by a
procedure or instructions that contains the function values by
repeatedly applying a given operation for many times to generate
the profit.

What is Recursion?

Recursion is a methodology in which a function calls itself as a
subroutine to the procedure. It allows the function to be repeated
several times, as it calls itself during its execution. It is often
considered an efficient programming technique as it needs the
minimum amount of code to perform the necessary functions and
rules. In other terms, we can say, Recursive definition is used to
divide more significant problems into subproblems and then
determine individual subproblems to prevent the problem complexity.
After solving each subproblem, the function of the subproblem will
be called by the primary function and can then retrieve the input’s
final output. There are so many advantages of recursion to get an
efficient output. Among them, one main reason to use this function
is, it generally allows a simple algorithmic solution to resolve
the particular problems that are practically unsolvable with an
iterative algorithm, and recursion is the best solution to think
about that with the use of a recursive sequence calculator.

How to determine this function?

Let’s see how to determine this function using the recursive
sequence calculator?

  • Step 1: First of all, get a clarified idea about what your
    function should do.
  • Step 2: Find out subproblem from function and assume your
    function already works on it.
  • Step 3: Develop the answer of your subproblem, and use it to
    determine the original problem.
  • % problem is solved, solve
    the base case to exploit the output and you are done with it.

So, I guess, from the above explanation of this formula, you are
clear about the method used in the recursive rule calculator. Now,
let’s discuss how to use this formula in the Recursive formula
calculator?

A recursion is defined as a particular class of object that can
be determined by two main properties:

  • Base case
  • Special rules to determine all other subcases

How to use Recursive formula calculator?

To solve the problem using Recursive formula calculator, follow
the mentioned steps:

  • In this calculator, you can solve either Fibonacci sequence or
    arithmetic progression or geometric progression. Choose one
    option.
  • After selection, start to enter input to the relevant field.
  • First, enter the value in the if-case statement. That should be
    used when a function or subclass is implemented and checks the
    eligibility and value of the function.
  • Then, add the function of the main problem that you have
    defined in the respective field. For example, to solve the
    Fibonacci sequence, add the function as f(n) = f(n-1)+f(n-2).
  • Now, add the value of n, where n is mentioned in function. So,
    it will be f(10).
  • Then, click on the submit button, and you will get the answer
    to function.

It is simple to operate the recursive rule calculator to solve
the recursion. Even, you can plot a graph using the formula that is
inserted in a calculator, and you can find out the result of
subproblems in a sequence and get a clear picture of how this
formula correctly works!!!

Moreover, you can solve the terms of the sequence online using
the Recursive Sequence calculator, defined by recurrence and its
first term, until the indicated index. It is also possible to
calculate the numerical sequence elements when set in the Recursive
Sequence calculator.

However, you can calculate numeric, arithmetic, or geometric
sequence using this calculator. We can define it as a series of
numbers indexed by an integer n, and generated by solving a
recurrence equation, which is represented by f(n), where f is a
symbol representing the sequence.

Recursive Sequence formula

The syntax of the recursion sequence can be defined as follows-
Recursive_sequence(expression; first-term;upper_value;variable)
Suppose, you are solving geometric sequence using recursive
sequence calculator than you should write like,
Recursive_sequence(4*x,-1,3,x);

Where, variable = x, first-term = -1, upper_value = 3, expression
= 4*x. You have to enter all these values in this calculator in the
respective field and click on the submit button. There will be an
output of the geometric sequence using recursion, and you can also
plot the series in the recursive rule calculator.

We can also consider this tool as a Recursive rule calculator, as
it is required to define such rules to develop the output of
subproblems, and then it will be merged to the main problem. That
is followed by some elementary functions which are recommended to
understand before using this calculator. Elementary functions are
addition, multiplication, Exponentiation, and Binomial
coefficients.

  • In recursive rule calculator, addition can be defined based on
    the counting values as, (1+n)+a =1+(n+a).
  • Followed by multiplication, it is defined recursively as,
    (1+n)a = a+na.
  • To defined Exponentiation in the recursive formula calculator,
    it will be written as, a1+n = aan.

Bottom Line

So, when you are defining rules to solve recursion functions, you
can go through the above elementary functions. Besides that, you
can also mention prime numbers, non-negative even numbers, and
other related formulas to function in recursive calculators to
solve the recursion. As it gives the result in a fraction of time
and provides efficient results to the function, it is always
recommended to go through the recursive formula calculator.

Recursive Formula Calculator -Recursive formula calculator is an
online tool which helps you do the hard calculations effectively by
dividing more significant problems into sub-problems. Use it now,
and thank us forever.Recursive Sequence Calculator

0 / 0 / 0

Регистрация: 20.11.2015

Сообщений: 60

1

Выведение рекуррентной формулы

18.09.2016, 20:51. Показов 9381. Ответов 6


Студворк — интернет-сервис помощи студентам

помогите вывести рекуррентную формулу и посчитать сумму членов ряда, больших заданного числа e. Предусмотреть ввод х и е. Не совсем понимаю, как выводить эту рекуррентную формулу. все какая-то ерунда получается..

https://www.cyberforum.ru/cgi-bin/latex.cgi?sum_{k=0}^{infty}, frac{{(1+x)}^{2k}}{k!};



0



Полярный

476 / 448 / 158

Регистрация: 11.09.2011

Сообщений: 1,156

18.09.2016, 21:34

2

Цитата
Сообщение от unior
Посмотреть сообщение

помогите вывести рекуррентную формулу

Рекуррентная формула – это когда каждый элемент выражен с помощью предыдущего (кроме самого первого). То есть нужно найти:

https://www.cyberforum.ru/cgi-bin/latex.cgi?{x}_{k+1}.

Исходя из предоставленной суммы выводим:

https://www.cyberforum.ru/cgi-bin/latex.cgi?{x}_{k} = frac{{(1 + x)}^{2k}}{k!}

Исходя из этого находим https://www.cyberforum.ru/cgi-bin/latex.cgi?{x}_{k+1}:

https://www.cyberforum.ru/cgi-bin/latex.cgi?{x}_{k+1} = frac{{(1 + x)}^{2(k + 1)}}{(k+1)!} = frac{{(1+x)}^{2k}}{k!} * frac{{(1 + x)}^{2}}{k + 1} = {x}_{k} * frac{{(1 + x)}^{2}}{k + 1}



1



0 / 0 / 0

Регистрация: 20.11.2015

Сообщений: 60

18.09.2016, 22:06

 [ТС]

3

на какому-то форуме говорили, что нужно сделать x(k)/x(k-1).. Теперь я окончательно запутался…



0



dimcoder

Полярный

476 / 448 / 158

Регистрация: 11.09.2011

Сообщений: 1,156

18.09.2016, 22:20

4

Лучший ответ Сообщение было отмечено unior как решение

Решение

Цитата
Сообщение от unior
Посмотреть сообщение

на какому-то форуме говорили, что нужно сделать x(k)/x(k-1)

И получится (1 + x)^2 / (k + 1). Теперь спросите их зачем. Вы попросили вывести рекуррентную формулу, я вам ее вывел. Зачем она тут конкретно, если есть формула суммации – непонятно. Ну только если требуется делать анализ, тогда может и надо. Если вам сумму надо посчитать с С++, то даю примерный код (не испытывал), если это просто мат задачка, то обратитесь в соответствующий раздел.

C++
1
2
3
4
5
6
7
8
double sum = 0, e = 0.3;
int limit = 1000;
for (int k = 0; k < limit; k++)
{
   double element = pow(1 + x, 2 * k) / factorial(k);
   if (element > e)
       sum += element;
}

Не забудьте написать функцию факториала.



1



_Ivana

4816 / 2276 / 287

Регистрация: 01.03.2013

Сообщений: 5,944

Записей в блоге: 27

18.09.2016, 23:02

5

Кот выше – ад и израиль.

C++
1
2
3
4
5
long double f(long double x, long double e) {
    long double t=1+x, r=0, a=1; t*=t; int i=1;
    do {r+=a; a=a*t/i++;} while (a>e);
    return r;
}



2



dimcoder

18.09.2016, 23:34

Не по теме:

Цитата
Сообщение от _Ivana
Посмотреть сообщение

Кот выше – ад и израиль.

Ага. Пожалуй теперь я понял для чего рекуррентная формула нужна была 😀 :pardon:



0



Mr.X

Эксперт С++

3222 / 1749 / 435

Регистрация: 03.05.2010

Сообщений: 3,867

19.09.2016, 13:26

7

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//вывести рекуррентную формулу и посчитать сумму членов ряда,
//больших заданного числа e. Предусмотреть ввод х и е.
///////////////////////////////////////////////////////////////////////////////
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
///////////////////////////////////////////////////////////////////////////////
typedef long double     T_float;
///////////////////////////////////////////////////////////////////////////////
T_float     series_sum
    (
        T_float     x,
        T_float     e
    )
{
    const
    T_float     T_INF   {
                            std::numeric_limits< T_float >::infinity()
                        };
 
    T_float     res     {};
    T_float     t       {1};
 
    for( int  k{}; t > e && res != T_INF; ++k )
    {
        if(k)
        {
            t   /=  k;
            t   *=  1 + x;
            t   *=  1 + x;
        }
 
        res     +=  t;
    }//for
 
    return  res;
}
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    for(;;)
    {
        T_float  x{};
        std::cout   <<  "xtt= ";
        std::cin    >>  x;
 
        T_float  e{};
        std::cout   <<  "ett= ";
        std::cin    >>  e;
 
        std::cout   <<  "series_sumt= "
                    <<  std::setprecision( std::numeric_limits< T_float >::digits10 )
                    <<  series_sum( x, e )
                    <<  std::endl
                    <<  std::endl;
    }//for
}



0



Время на прочтение
6 мин

Количество просмотров 33K

Пеленгский фермер Бух’ерик разводит хрякоплюхов. Эти животные размножаются так быстро, что их поголовье ежедневно возрастает в 3 раза. Но, начиная со второго дня, на ферму повадилась нападать стая страшных зверей долбогрызов, каждый вечер пожирающих вдвое больше хрякоплюхов, чем их было в предыдущий день. Сколько хрякоплюхов будет у фермера на 7-й вечер, если вначале их было 10?

Вы спросили у гаальца, что он думает по поводу этой задачки. После некоторого размышления тот ответил:
— В начале было 10 хрякоплюхов. В первый день они размножились, и к началу второго дня их стало 30. Во второй день они опять размножились (их стало 90), но вечером пришли долбогрызы и съели вдвое больше хрякоплюхов, чем было вчера (в первый день), т.е. 20 штук. Итого, в начале третьего дня получаем 70 хрякоплюхов. Мне кажется, что, продолжая решать таким образом, можно вычислить число хрякоплюхов в любой день.

Это задача из игры «Космические Рейнджеры 2», квест Амнезия.
Попробуем вывести формулу для количества хрякоплюхов на n-ный день, и посчитать для примера количество хрякоплюхов на 32-й день.

Посмотрим на первые несколько дней (я добавил день «0» только для удобства формулы, можно все делать и без него)

День «0» День 1 День 2 День 3
Утро 0 10 30 70
После размножения 0 10 * 3 = 30 30 * 3 = 90 70 * 3 = 210
После долбогрызов (вечер) 0 10 * 3 — 0 * 2 = 30 30 * 3 — 10 * 2 = 70 70 * 3 — 30 * 2 = 150

Нас будет интересовать количество хрякоплюхов на утро n-ного дня, и, несмотря на то, что в задаче спрашивается про вечер, верным будет утреннее количество.
Таким образом, количество хрякоплюхов (на утро) являет собой последовательность

$F = (0, 10, 30, 70, ...)$

Про эту последовательность мы знаем (по условию задачи) что

$F_0 := 0$ и

$F_1 := 10$

Так же, по условию задачи, ночью ничего не происходит, поэтому хрякоплюхи вечером в полном составе без изменений переносятся на утро следующего дня (т.е. количество хрякоплюхов утром равно их количеству вечером предыдущего дня).

Т.е. на утро второго дня их стало

$F_2 = 30 = 3 * 10 - 2 * 0 = 3 * F_1 - 2 * F_0$.
На утро третьего дня их уже

$F_3 = 70 = 3 * 30 - 2 * 10 = 3 * F_2 - 2 * F_1$.

День n-2 День n-1 День n
Утро $F_{n-2}$ $F_{n-1}$ $F_{n} = 3*F_{n-1} - 2*F_{n-2}$
После размножения $3 * F_{n-2}$ $3 * F_{n-1}$ $3 * F_{n}$
После долбогрызов (вечер) $3 * F_{n-2} - 2 * F_{n-3}$ $3 * F_{n-1} - 2 * F_{n-2}$ $3 * F_{n} - 2 * F_{n-1}$

Начиная со второго дня

$n=2$ действует такая рекуррентная формула:

$F_{n} = 3 * F_{n-1} - 2 * F_{n-2}$

Итого, ещё раз всё вместе

$ F_0 := 0 \ F_1 := 10 \ F_{n} = 3 * F_{n-1} - 2 * F_{n-2} $

Мы получили формальное определение последовательности и этого уже достаточно чтобы можно было вручную посчитать сколько будет хрякоплюхов на какой день. Более того, если у нас магическим образом появилась какая-то формула для

$F_n$, и эта формула выполняется для этих 3-х условий, то эта формула будет тем, что нам нужно.

Мы же будем пытаться получить эту формулу.

Как правило, чтобы что-то найти нужно составить уравнение, поэтому так и поступим.
Наша последовательность

$F$ — это то, что мы хотим найти (точнее, мы хотим получить формулу для её членов).

Будем делать уравнение из последовательностей. Для этого изобретём сложение для последовательностей:

$"A+B"=(A_0 + B_0, A_1 + B_1, ....)$

Т.е. сумма последовательностей есть тоже последовательность.

Важно упомянуть что наши последовательности вообще-то бесконечные, и так просто что-то с ними делать нельзя. Нельзя, к примеру, безо всяких оговорок просуммировать все члены последовательности — никто не может бесконечное время сидеть и суммировать.

Бесконечная последовательность — это то, где для любого номера члена мы можем сказать как его посчитать за конечное время. В случае последовательности

$F$ мы как бы говорим: возьмите день0, возьмите день1 и далее потихоньку, шаг за шагом, считайте следующие дни пока не дойдёте до нужного вам.

Для суммы последовательностей мы говорим: если вам нужен 100-й член суммы, то возьмите по 100-му члену из слагаемых последовательностей и сложите их. Нужен миллионный — так же, возьмите миллионный там, возьмите миллионный сям, сложите эти числа и получите что вам нужно.

Это похоже на то, как суммируются многочлены, к примеру:

$(3 + 2x + x^2) + (6 + 4x^2) = (3+6) + (2+0)x + (1+4)x^2$

.

Можно даже представить себе бесконечный многочлен

$A = A_0 + A_1*x + A_2 * x^2 + A_3 * x^3 + ... $

где

$x, x^2, x^3, ..., x^n, ... $ — просто какие-то символы. И если мы складываем два таких «бесконечночлена», то их сумма будет как раз сумма последовательностей (мы так определили сумму последовательностей).

Тут важно понимать что на самом деле нет никаких бесконечных многочленов, это просто иная но более удобная запись бесконечной последовательности: пишем

$F = 10x + 30x^2 + 70x^3 + ...$, а видим

$F = (0, 10, 30, 70, ...)$.

Теперь придумаем умножение для последовательностей. Просто попарно перемножить члены так же как со сложением не пойдёт — хотя это и будет похоже на умножение, интересных свойств это не даст. Да и хочется чтобы умножение было бы похоже на умножение многочленов.

К примеру, вот так умножаются обычные конечные многочлены:

$(a_0 + a_1*x + a_2*x^2) * (b_0 + b_1*x + b_2*x^2) = ???$

Берутся и перемножаются: раскрываются скобки, и группируются члены с одной и той же степенью икса

$ (a_0 + a_1*x + a_2*x^2) * (b_0 + b_1*x + b_2*x^2) = \ a_0 * (b_0 + b_1*x + b_2*x^2) + a_1*x * (b_0 + b_1*x + b_2*x^2) + \ a_2*x^2 * (b_0 + b_1*x + b_2*x^2) = \ a_0 * b_0 +\ x(a_0*b_1 + a_1*b_0) + \ x^2*text{(...что-то длинное...)} + \ x^3*text{(...что-то длинное...)} + \ x^4*text{(...что-то длинное...)} $

Другими словами, каждый член первого многочлена умножается на каждый член второго.
Каждый с каждым.

Так просто это обобщить на бесконечные последовательности нельзя — опять же, потому что никто не может бесконечное количество раз умножить на бесконечное количество элементов. Тут важно правильно сказать, а именно что пускай n-ный член произведения последовательностей равен

$"A*B"_n := A_0*B_n + A_1*B_{n-1} + A_2 * B_{n-2} + ... + A_n * B_0 = sum_{i=0}^{i=n} A_i*B_{n-i}$

Почему именно так

В самом деле, если вам интересно что стоит на 100-м месте, т.е. какой коэффициент у

$x^{100}$, то вы вполне можете сказать:

$x^{100}$ может получиться если умножились

$a_0 * b_{100}*x^{100}$. Также

$x^{100}$ может получиться если умножились

$a_1*x * b_{99}*x^{99}$. Можно сообразить и привести всю 101 пару членов, которые при перемножении дадут

$x^{100}$. И после этого упомянуть что больше никак

$x^{100}$ в произведении не может получится.

Теперь мы умеем складывать бесконечные последовательности и так же умеем их перемножать. Можно заметить некоторые хорошие свойства, к примеру что

$A+B = B+A$;

$A*B = B*A$;

$A*(B+C)=A*B + A*C$. Мы придумали это сложение и умножение, нужно обязательно проверять что такие свойства выполняются (это «группа» и «кольцо»). Это несложно проверить, и, в целом-то, эти все свойства довольно естественны, особенно для тех кто хоть сколько-то складывал и умножал конечные многочлены.

Попробуем теперь для примера посчитать

$100 * F = (100, 0, 0, 0, .....)*(F_0, F_1, F_2, F_3, ...)$. Согласно определению умножения получаем

$ "100*F"_n = sum_{i=0}^{i=n} (100, 0, 0, 0, 0, ....)_i*F_{n-i} = 100*F_{n} $

Выглядит логично — умножение последовательности на число даст умножение каждого члена на это число. И это сходится с

$ 100 * (F_0 + F_1x + F_2x^2 + ...) = 100F_0 + 100F_1x + 100F_2x^2 + ... $

Важное замечание:

$1 * F = F * 1 = F$, где соответственно

$ 1 = (1, 0, 0, 0, ....)$

Теперь посчитаем

$x * F = (0, 1, 0, 0, .....)*(F_0, F_1, F_2, F_3, ...)$. Так же согласно определению умножения получаем

$ "x*F"_n = sum_{i=0}^{i=n} (0, 1, 0, 0, 0, ....)_i*F_{n-i} = F_{n-1} text{при n > 0, либо 0 при n = 0} $

Т.е.

$ "x*F" = (0, F_0, F_1, F_2, F_3, ...) $

Что, собственно, так же сходится с

$ x * (F_0 + F_1x + F_2x^2 + ...) = F_0x + F_1x^2 + F_2x^3 + ... $

Так же получаем что

$x^2 * F = (0, 0, F_0, F_1, F_2, ...)$.

Это базовые операции над нашей последовательностью, и теперь вот это всё хорошо бы собрать и применить к начальной рекуррентной формуле

$F_{n} - 3 * F_{n-1} + 2 * F_{n-2} = 0$:

$ F = (F_0, F_1, F_2, ...)\ 3 * x * F = (0, 3F_0, 3F_1, 3F_2, ....)\ 2 * x^2 * F = (0, 0, 2F_0, 2F_1, 2F_2, ....) $

Из первой строчки вычитаем вторую и прибавляем третью:

$ F - 3 * x * F + 2 * x^2 * F = \ (F_0 - 0 + 0, F_1 - 3F_0 + 0, F_2 - 3F_1 + 2F_0, ...., F_{n} - 3 * F_{n-1} + 2 * F_{n-2}) = \ (F_0, F_1 - 3F_0, 0, 0, 0, ....) = F_0 + (F_1 - 3F_0)x = 10x $

Итого получаем (используя хорошие свойства сложения и умножения):

$ F*(1 - 3x + 2x^2) = 10x $

что, напомню еще раз, на самом деле

$ (F_0, F_1, F_2, ....)*(1, -3, 2, 0, 0, ....) = (0, 10, 0, 0, ....) $

Это и есть уравнение, и его мы будем решать. Мы не можем взять так просто и поделить на

$(1 - 3x + 2x^2)$, хотя бы потому что мы не определяли операцию деления. Вместо этого мы будем умножать обе части уравнения на что-то такое, что как бы является

$(1 - 3x + 2x^2)^{-1}$, и в конечном итоге оставим одинокую F слева.
На текущий момент из того что мы имееем мы не можем достоверно сказать существует ли вообще такое

$(1 - 3x + 2x^2)^{-1}$ (хотя так-то оно существует, и мы его сейчас сделаем).

Почему можно умножить обе части уравнения на что-то

Если у нас есть какие-то

$A$ и

$B$, да и при том такие что

$A=B$, то

$ A = B Rightarrow A*C = B*C $

Но из этого абсолютно не следует что если

$A*C = B*C$, то

$A=B$. К примеру, из того что

$4*0 = 5*0$ вовсе не следует что

$4 = 5$.
Для того, чтобы было верно

$ A = B Leftrightarrow A*C = B*C $

нужно чтобы существовал такой элемент

$D$, что

$C*D = 1$.
Тогда можно получить что

$A*C = B*C implies A*C*D = B*C*D implies A = B$

Немного преобразуем наше уравнение:

$ F*(1 - 3x + 2x^2) = 10x \ Leftrightarrow \ F*(1-x)(1/2-x)*2 = 10x $

Это, опять же, не просто так, это потому что последовательность

$(1, -1, 0, 0, 0, ...)$ умноженная на

$(1/2, -1, 0, 0, 0, ...)$ и умноженная на

$(2, 0, 0, 0, ...)$
даёт в результате

$(1, -3, 2, 0, 0, 0, ...)$
Вот теперь уже чуть легче, теперь хорошо бы отыскать такие

$"(1-x)^{-1}"$ и

$"(1/2-x)^{-1}"$, да и умножить на них наше уравнение.
Такие обратные последовательности есть, и вот их формула

$ (alpha - x)*(1/alpha + x/alpha^2 + x^2/alpha^3 + .... + x^{n-1}/alpha^{n} + ...) = \ alpha * 1/alpha - x*1/alpha + alpha*x/alpha^2 + .... = 1 $

Как это можно получить

Для начала попробуем на простом случае, с

$alpha = 1$:

$ (1 - x)*(A_0 + A_1x + A_2x^2 + ...) = 1 $

Ясно что

$A_0 = 1$, тут без вариантов. Теперь посмотрим что может получится у 1-й степени x:

$-x*A_0 + 1*A_1x = -x*1 + 1*A_1x$ (я просто покомпонентно перемножаю первую последовательность на вторую). Ясно что

$A_1 = 1$. Так же далее получаем что

$A_n = 1$.
Для общего случая

$(alpha - x)$ действуем подобным образом.

Таким образом, умножаем обе части уравнения:

$ F*(1-x)(1/2-x)*2 = 10x \ Leftrightarrow \ F*(1-x)(1/2-x)*2 * (1 + x + x^2 + x^3 + ...) * (2 + 4x + 8x^2 + ... + 2^{n+1}x^n + ...) * \ (1/2) = 10x *(1 + x + x^2 + x^3 + ...) * (2 + 4x + 8x^2 + ... + 2^{n+1}x^n + ...) * (1/2) \ Leftrightarrow \ F = 5x * (1 + x + x^2 + x^3 + ...) * (2 + 4x + 8x^2 + ... + 2^{n+1}x^n + ...) \ Leftrightarrow \ F = 10x * (1 + x + x^2 + x^3 + ...) * (1 + 2x + 4x^2 + ... + 2^{n}x^n + ...) $

Посмотрим повнимательней на

$ (1 + x + x^2 + x^3 + ...) * (1 + 2x + 4x^2 + ... + 2^{n}x^n + ...) = \ (1, 1, 1, ...., 1, ....) * (1, 2, 4, ...., 2^{n}, ...) $

По определению произведения получаем формулу для n-ного члена:

$ "(1, 1, 1, ...., 1, ....) * (1, 2, 4, ...., 2^{n}, ...)"_{n} = \ "(1, 2, 4, ...., 2^{n}, ...) * (1, 1, 1, ...., 1, ....)"_{n} = \ sum_{i=0}^{i=n} A_i*B_{n-i} = \ sum_{i=0}^{i=n} 2^{i} = \ 1 + 2 + 4 + .... + 2^n = 2^{n+1} - 1 $

Откуда появился последний шаг

Это обычная сумма членов конечной геометрической прогрессии. Можно по-быстрому получить вот так:
Пусть

$S_n = 1 + 2 + 4 + ... + 2^n$. Тогда

$S_{n+1} = 1 + 2 + .... + 2^n + 2^{n+1} = S_n + 2^{n+1}$.
В то же время,

$2 * S_n = 2 + 4 + 8 + ... + 2^{n+1} = 1 + 2 + 4 + 8 + ... + 2^{n+1} - 1 = S_{n+1} - 1 $ следовательно

$S_{n+1} = 2*S_n - 1$
Итого приравнивая

$S_{n+1}$ получаем

$S_n + 2^{n+1} = 2*S_n - 1 implies S_n = 2^{n+1} - 1$.

Подставляем полученное произведение

$ F = 10x * (1 + x + x^2 + x^3 + ...) * (1 + 2x + 4x^2 + ... + 2^{n}x^n + ...) \ Leftrightarrow \ F = 10x * (1, 3, 7, ..., 2^{n+1} - 1, ...) \ Leftrightarrow \ F = (0, 10, 30, 70, ...., 10*(2^{n} - 1), ...) $

При умножении на

$10x = (0, 10, 0, 0, 0, ...)$ все члены умножились на 10 и сдвинулись на 1 вправо.
Итого получаем результат

$ F_n = 10*(2^{n} - 1) $

Именно эту формулу нужно использовать для прохождения квеста, и именно её можно найти в подсказках в квесте.
К примеру на 32-й день получаем

$F_{32} = 10*(2^{32} - 1) = 42949672950$.
Глядя на формулу можно сказать что хрякоплюхам долбогрызы не помеха — они даже будучи поедаемыми успевают экспоненциально размножаться.

Таким же образом можно вывести формулу для n-ного члена последовательности Фибоначчи, правда там числа будут пострашней — с корнями, и при этом при любом n формула даст натуральное число.

Немного размышлений о сложности алгоритма

Если реализовывать алгоритм расчета хрякоплюхов согласно рекуррентному определению (необязательно при этом использовать рекурсию), то сложность получается O(n).
А вот если по формуле — то тут можно и поспорить, будет ли это O(n) либо O(1). Зависит как мы считаем 2**n — это O(1) или O(n). С одной стороны, это битовый сдвиг, с другой стороны при n больших чем разрядность процессора потребуется больше времени на вычисления.
К примеру, если сделать Ethereum контракт, который будет считать этих хрякоплюхов, и посмотреть что получится по потреблению gas в зависимости от алгоритма:

Код на solidity

pragma solidity ^0.4.0;

contract Rangers {
    /*
    10 -> 1335 gas 
    20 -> 2385 gas
    30 -> 3435 gas
    40 -> 4485 gas
    50 -> 5535 gas
    60 -> 6585 gas
    70 -> 7635 gas
    80 -> 8685 gas
    90 -> 9735 gas
    100 -> 10785 gas
    */
    function byStepByStep(uint n) public pure returns (uint) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 10;
        }
        uint result = 10;
        uint prev1 = 10;
        uint prev2 = 0;
        for (uint i = 2; i <= n; i++) {
            result = 3*prev1 - 2*prev2;
            prev2 = prev1;
            prev1 = result;
        }
        return result;
    }
	
    /*
     10 -> 310 gas
     100 -> 310 gas
     200 -> 310 gas
    */
    function byFormula(uint n) public pure returns (uint) {
        return 10*(2 ** n - 1);
    }   
}

То вполне предсказуемо получится что по шагам будет O(n), а по формуле самый настоящий O(1).

Добавить комментарий