zoukankan      html  css  js  c++  java
  • 【欧拉计划2】Even Fibonacci numbers

    欢迎访问我的新博客:http://www.milkcu.com/blog/

    原文地址:http://www.milkcu.com/blog/archives/1367386440.html

    该题来自Project Euler第二题,求数值小于4百万的偶数项的和。今天继续的欧拉计划。


    问题描述

    英语原文

    Even Fibonacci numbers

    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.

    中文描述

    在Fibonacci数列中,每一项由它的前两项之和生成。从1,2开始,前十项为:
    1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
    考虑Fibonacci数列中数值不超过4百万的项,求出值为偶数的项的和。

    解决方案

    我的解法

    这是中规中矩的方法,用了点循环队列的思想,虽然可以用几个变量替代。在写代码的过程中,还犯了一个傻傻的错误,感谢论坛朋友的帮助。

    # include <stdio.h>
    # define BOUND 4000000
    
    int main(void)
    {
    	int fib[3];
    	int i;
    	long long int sum;
    	
    	fib[0] = 1;
    	fib[1] = 2;
    	sum = 2;
    	for(i = 2; fib[(i - 1) % 3] < BOUND; i++) {
    		fib[i % 3] = fib[(i - 1) % 3] + fib[(i - 2) % 3];  //队列的思想 
    		if(fib[i % 3] % 2 == 0) {
    			sum += fib[i % 3];
    		}
    	}
    	printf("%d\n", fib[(i - 2) % 3]);
    	printf("%d", sum);
    }

    下面是题目解析提供的几种解法。

    直接求解

    这个方法和我的方法原理是一样的。

    # include <stdio.h>
    int main(void)
    {
    	int limit;
    	int a, b, h;
    	int sum;
    	
    	limit = 4000000;
    	a = b = 1;
    	sum = 0;
    	while(b < limit) {
    		if(b % 2 == 0) {
    			sum += b;
    		}
    		h = a + b;
    		a = b;
    		b = h;
    	}
    	printf("%d", sum);
    }

    另一种方法

    仔细观察数列,可以发现,每三个Fibnacci数有一个偶数。利用这个规律,可以省去条件判断。

    # include <stdio.h>
    int main(void)
    {
    	int limit;
    	int a, b, c;
    	int sum;
    	
    	limit = 4e6;
    	a = 1;
    	b = 1;
    	c = 2;
    	sum = 0;
    	while(c < limit) {
    		sum += c;
    		a = b + c;
    		b = a + c;
    		c = a + b;
    	}
    	printf("%d", sum);
    }

    高效方案

    如果把偶数项拿出来:
    2,8,34,144……

    它们遵循的这样的规律:
    E(n)=4*E(n-1)+E(n-2)

    # include <stdio.h>
    int main(void)
    {
    	int limit;
    	int a, b;
    	int sum;
    	
    	limit = 4e6;
    	sum = 2;
    	a = 2;
    	b = 8;
    	while(b < limit) {
    		sum += b;
    		b = 4 * b + a;
    		a = (b - a) / 4;    //在没有使用第三变量的情况下,变量后移
    	}
    	printf("%d", sum);
    }

    要证明上关系式成立,只需证:
    F(n)=4*F(n-3)+F(n-6)

    证明过程如下:
    F(n) = F(n-1) + F(n-2) 
    = F(n-2)+F(n-3)+F(n-2)=2 F(n-2) + F(n-3) 
    = 2(F(n-3)+F(n-4))+F(n-3))=3 F(n-3) + 2 F(n-4) 
    = 3 F(n-3) + F(n-4) + F(n-5) + F(n-6) 
    = 4 F(n-3) + F(n-6)

    最后答案

    4613732

  • 相关阅读:
    「CF1335E Three Blocks Palindrome」
    「高等数学学习笔记 DAY23」
    「高等数学学习笔记 DAY22」
    「CF911G Mass Change Queries」
    「CF689D Friends and Subsequences」
    「高等数学学习笔记 DAY21」
    「高等数学学习笔记 DAY20」
    「高等数学学习笔记 DAY19」
    「Luogu P6242 【模板】线段树 3」
    【POJ3278】Catch That Cow
  • 原文地址:https://www.cnblogs.com/milkcu/p/3808898.html
Copyright © 2011-2022 走看看