Найти сумму первых n чисел Фибоначчи

Рейтинг: -1Ответов: 3Опубликовано: 17.03.2023

Задание: для натурального числа n (в данном случае это 8 и 11) найти значение результата равного первым n чисел Фибоначчи. Я пытался сделать по такому коду, но оно вместо этого выводит 32 и 143. Второй результат правильный но первый почему-то нет:

    int n0 = 0;
    int n1 = 1;
    int n2 = 1;
    int result = n;

for(int i=2; i<n; i++) {
    result = n1 + n0 + n1;
    n0 = n1;
    n1= n2;
    n2 = result+1;
}


    return result;

Ответы

▲ 1

Как известно, сумма N чисел Фибоначчи от F(1) до F(N) равна F(N + 2) - 1, поэтому для её вычисления достаточно вызвать метод для вычисления обычного числа Фибоначчи.

public static long sumF(long n) {
    return fib(n + 2) - 1; // или fibRec(n + 2) - 1
}

// рекурсивное вычисление
public static long fibRec(long n) {
    if (n < 2) return n;
    return fibRec(n - 1) + fibRec(n - 2);
}

// итеративное вычисление
public static long fib(long n) {
    if (n < 2) return n;
    long a = 0, b = 1, f = 1;
    for (int i = 1; i < n; i++) {
        f = a + b;
        a = b;
        b = f;
    }
    return f;
}

Тест:

System.out.println(sumFib(8));  // -> 54 
System.out.println(sumFib(11)); // -> 232

Для вычисления суммы N чисел, начиная с F(0) = 0, достаточно изменить формулу на F(N + 1) - 1:

public static long sumFfrom0(long n) {
    return fib(n + 1) - 1; // или fibRec(n + 1) - 1
}
▲ 1

Давайте посчитаем сумму первых чисел Фибоначчи.

У ряда есть два варианта, оба встречаются часто, поэтому мы можем выбрать любой. Первый ряд начинается с 0, 1, 1, 2...; второй — с 1, 1, 2, 3...

Пусть у нас будет первый ряд.

n Fib(n) Sum(Fib(n))
0 0 0
1 1 1
2 1 2
3 2 4
4 3 7
5 5 12
6 8 20
7 13 33
8 21 54
9 34 88

Мы видим формулу, про которую сказано в соседнем ответе: Sum(Fib(n)) = Fib(n + 2) - 1. Я заинтересовался, откуда это известно.

Мне показалось что её легко вывести по индукции.

Предположим, что Sum(Fib(n)) = Fib(n + 2) - 1 для какого то n.

Тогда Sum(Fib(n + 1)) = Sum(Fib(n)) + Fib(n + 1). Если верно первое равенство, то второе равенство равно Fib(n + 2) - 1 + Fib(n + 1). Но Fib(n + 1) + Fib(n + 2) = Fib(n + 3), следовательно, второе равенство это Fin(n + 3) - 1. Следовательно, Sum(Fib(n + 1)) = Fib(n + 3) - 1. Обозначив n + 1 = m, можем записать его как Sum(Fib(m)) = Fib(m + 2) - 1.

Шаг индукции мы доказали. Убедимся, что Sum(Fib(n)) = Fib(n + 2) - 1 для n = 0, 1, 2, 3... Из таблицы выдим, что это так.

Так что да, простейший способ это формула, доказанная по индукции. Либо можете посчитать сумму вручную:

public class MyClass {
    static final int N = 9;
    
    public static void main(String args[]) {
        int a = 0;
        int b = 1;
        int sum = a + b;
        for (int i = 2; i <= N; i++) {
            int t = a;
            a = b;
            b = t + b;
            sum += b;
        }
        
        System.out.format("Sum(Fib(%d)) = %d", N, sum); // => 88
    }
}

Всё, как в таблице.

▲ -1

Имхо, проще пробежаться по числам Фибоначчи и вычислить их сумму. Пример на C#

int getFibSum(int n)
{
    if (n == 1) return 0;
    if (n == 2) return 1;

    int n1 = 0;
    int n2 = 1;
    int ret = 1;

    for (int i = 3; i <= n; i++)
    {
        var n3 = n1 + n2;
        ret += n3;
        n1 = n2;
        n2 = n3;
    }

    return ret;
}

Проверка

Console.WriteLine(getFibSum(8));
Console.WriteLine(getFibSum(11));

Вывод

33
143