问题描述如下:
“Fibonacci 数列n>=2的前10个数如下:
1,2,3,5,8,13,21,34,55,89...求Fibonacci sequence中400w以下的偶数之和”
注意:如果是10以下的偶数之和为2+8,如果是89以下的偶数之和为2+8+34,以此类推
Fibonacci sequence的由来就不详细介绍了,有兴趣可以去了解。
其基本概念如下:
n=0,f(0)=0;
n=1,f(1)=1;
n=2,f(2)=f(1)+f(0)=1;
n,f(n)=f(n-1)+f(n-2)(n>=2);
问题实现代码如下:
public static int getSum(int limit) {
int sum = 0;
int f1 = 1; // 默认值
int f0 = 0; // 默认值
int fn = 0;
for (int i = 0; fn < limit; i++) {
fn = f1 + f0;
if (fn % 2 == 0) {
sum += fn;
}
f0 = f1;
f1 = fn;
}
return sum;
}
可以得到结果为4613732,调试时发现int够用。如果在需要的情况下,可以将int改为long来执行。
public static Long getSum(int limit) {
Long sum = 0L;
Long f1 = 1L; // 默认值
Long f0 = 0L; // 默认值
Long fn = 0L;
for (int i = 2; fn < limit; i++) {
fn = f1 + f0;
if (fn % 2 == 0) {
sum += fn;
}
f0 = f1;
f1 = fn;
}
return sum;
}
将Fibonacci sequence单列一个函数,方便其他使用:
public static int f(int n) {
int fn;
if (n == 0) {
fn = 0;
} else if (n == 1) {
fn = 1;
} else {
fn = f(n - 1) + f(n - 2);
}
return fn;
}
public static int getSum2(int limit) {
int sum = 0;
int i = 2;
int fn = f(i);
while (fn < limit) {
if (fn % 2 == 0) {
sum += fn;
}
fn = f(++i);
}
return sum;
}
这样就结束了么?答案是没有。
通过观察我们可以发现,f(3),f(6),f(9)...这些项为偶数。也就是说n项可以被3整除时,那第n项就为偶数。
上面结论可以使用Fibonacci sequence递归得证,即f(n)=f(n-1)+f(n-2)=2*f(n-2)+f(n-3),f(n-3)为偶数,那么f(n)也为偶数,得证。
那求和就为sum=f(3)+f(6)+...+f(3n),其中f(3n)<4000000.那么可以求得n,假设n的值为a,
2*sum = 2*(f(3)+...+f(3k))=f(1)+f(2)+f(3)+...+f(3a-2)+f(3a-1)+f(3a),Fibonacci sequence前n项和有规律f(1)+f(2)+f(3)+...+f(n)=f(n+2)-1(此公式可以通过递推关系和数学归纳法证明),
那么,可以得到sum=(f(a+2)-1)/2,a值代入,即可得结果。
实现一下代码:
public static int getSum3(int limit) {
int sum = 0;
int i = 2;
int fn = f(i);
while (fn < limit) {
fn = f(++i);
}
return (f(i + 1) - 1) / 2;
}
先这么结束吧!
请不吝赐教。@anthor ClumsyBirdZ