PE2 Even Fibonacci numbers(最大菲波那列偶数)

本系列前言PEProject Eluer)是学Mathematica(以后我简称Mma)接触到的,不用提交代码,只用提交答案的答题网站。PE的题目会给出C++Mma代码实现,以此学习Mma(已经被它的简洁给折服了..)。

 

题目

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

https://projecteuler.net/problem=2

分析

 

题目求由不小于四百万的偶数之和。

Fibonacii算法复习

这里涉及到求Fibonacii数列的算法,一般来说有如下几种:

n  二分递归法:用递推公式,Fn = F(n-1)+F(n-2)O(2n)

n  线性递归法:用态规划思想,保存解。TimeO(n) PlaceOn

n  迭代:On),由于迭代法完胜递归法,前两种方法平时基本不用去使用;

n  其他方法(二分矩阵、公式法

Code部分贴上前三种方法,作为复习Fibonacii算法(我只会这三种)。

偶数求和分析:

1.     暴力法:循环到大于4000000结束,依次算出每个数的Fn,偶数则加和。On

int FibEvenSum1(intlimit){

   int sum = 0;

   int a = 0;

   int b = 1;

   while (a<limit)

   {

       int c = b;

       b += a;

       a = c;

       if (a % 2 == 0) sum += a;

       cout << "sum:" << sum << endl;

   }

   return sum;

}

2.     Mma列举出几个Fib看看(Mma实在太适合干这个了。。。)

I Fibonacci@Range[1, 20]

O:  {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765}

得到规律:其中偶数的序列为:F3F6F9…….所以可以从这里入口优化。

int FibEvenSum2(intlimit){

int sum = 0;

int a = 1;

int b = 1;

int c = a + b;

while (c<limit)

{

     sum += c;

     a = b + c;

     b = c + a;

     c = a + b;

     cout << "sum:" << sum << endl;

}

return sum;

}

效率提高2倍,还有更beautify….

3.  再次用Mma观察

I :              Fibonacci@Range[1, 20] // Select@EvenQ

O:             {2, 8, 34, 144, 610, 2584}

设新数列为EnEn = 4*En-1+En-2

如何来的呢?Fn  =  Fn-1+Fn-2

                     =  2Fn-2+Fn-3

                        =  4F(n-3) + F(n - 6)

用这个递推公式优化后,效率在2的基础上提高3

int FibEvenSum3(intlimit){

int a = 0;

int b = 2;

int c = 0;

int sum = 0;

while (c < limit){

     a = 4 * c + b;

     b = 4 * a + c;

     c = 4 * b + a;

     if (c < limit)sum += c;

     if (b < limit)sum += b;

     if (a < limit)sum += a;

     cout << "sum:" <<sum <<endl;

}

 return sum;

}

Code

#include <iostream>
using namespace std;
int FibEvenSum1(int limit);
int FibEvenSum2(int limit);
int FibEvenSum3(int limit);
int main(){

    int d = FibEvenSum1(4000000);
    cout << endl;
    int f = FibEvenSum2(4000000);
    cout << endl;
    int r = FibEvenSum3(4000000);
    return 0;
}


int FibEvenSum1(int limit){
    int sum = 0;
    int a = 0;
    int b = 1;
    while (a<limit)
    {
        int c = b;
        b += a;
        a = c;
        if (a % 2 == 0) sum += a;
        cout << "sum:" << sum << endl;
    }
    return sum;
}
/*1 1 2 3 5 8 13 21 34 每三个数出现一个偶数*/
int FibEvenSum2(int limit){
    int sum = 0;
    int a = 1;
    int b = 1;
    int c = a + b;
    while (c<limit)
    {
        sum += c;
        a = b + c;
        b = c + a;
        c = a + b;
        cout << "sum:" << sum << endl;
    }
    return sum;
}

int FibEvenSum3(int limit){
    int a = 0;
    int b = 2;
    int c = 0;
    int sum = 0;
    while (c < limit){
        a = 4 * c + b;
        b = 4 * a + c;
        c = 4 * b + a;
        if (c < limit)sum += c;
        if (b < limit)sum += b;
        if (a < limit)sum += a;
        cout << "sum:" <<sum <<endl;
    }
     return sum;
}
EvenFibSum

 

#include <iostream>

using namespace std;
__int64 fib(int i);
__int64 fib2(int n, __int64 & prev);
__int64 fib3(int n);
long main(){

    cout << fib(10);
    cout << fib3(10);
    return 0;
}
__int64 fib(int n){
    return (2>n) ? (__int64)n:fib(n - 1) + fib(n - 2);
}
__int64 fib2(long n, __int64 & prev){//第n项、prev:n-1项的值
    if (0 == n){//直接取值:fib(-1) = 1;fib(0) = 0;
        prev = 1;
        return 0;
    }
    else{
        __int64 prevPrev;
        prev = fib2(n - 1, prevPrev);
        return prevPrev + prev;
    }
}

__int64 fib3(int n){
    __int64  f = 0, g = 1;//初始化:fib(0) = 0,fib(1) = 1;
    while (0<n--)
    {
        g += f;
        f = g - f;
    }
    return f;
}
Fibonacci

Mathematica  

Fibonacci@Range[1, 33] // Select@EvenQ // Total

简单粗暴!

 

 

参考:  1.邓俊辉.数据结构(C++语言版).第三版.清华大学出版社.第一章

        2.hk

 

原文地址:https://www.cnblogs.com/dingblog/p/4500170.html