该题来自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