题目: 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
程序分析
这是一个典型的斐波那契数列问题,可以用递归、迭代和动态规划三种方法来解决。斐波那契数列满足递推关系:F(n) = F(n-1) + F(n-2),其中 F(1) = F(2) = 1。
方法1: 递归
递归是最直观的方法,但可能会产生大量重复计算,效率较低。
#include <stdio.h>
int fibonacci_recursive(int n) {
if (n <= 2)
return 1;
else
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2);
}
int main() {
int months = 40;
for (int i = 1; i <= months; i++)
printf("Month %d: %d\n", i, fibonacci_recursive(i));
return 0;
}
方法2: 迭代
迭代方法避免了递归中的重复计算,效率更高。
#include <stdio.h>
int fibonacci_iterative(int n) {
int a = 1, b = 1, temp;
if (n <= 2)
return 1;
for (int i = 3; i <= n; i++) {
temp = a + b;
a = b;
b = temp;
}
return b;
}
int main() {
int months = 40;
for (int i = 1; i <= months; i++)
printf("Month %d: %d\n", i, fibonacci_iterative(i));
return 0;
}
方法3: 动态规划
动态规划方法在计算过程中保存了中间结果,避免了重复计算,效率更高。
#include <stdio.h>
int fibonacci_dynamic(int n) {
int fib[n + 1];
fib[1] = 1;
fib[2] = 1;
for (int i = 3; i <= n; i++)
fib[i] = fib[i - 1] + fib[i - 2];
return fib[n];
}
int main() {
int months = 40;
for (int i = 1; i <= months; i++)
printf("Month %d: %d\n", i, fibonacci_dynamic(i));
return 0;
}
解题思路及优缺点
- 递归方法直接按照问题描述实现,容易理解,但效率低,存在大量重复计算,不适用于大规模计算。
- 迭代方法通过迭代计算避免了重复计算,效率较高,适用于中等规模计算,但空间复杂度为O(1)。
- 动态规划方法利用数组保存中间结果,避免了重复计算,效率高,适用于大规模计算,但空间复杂度较高为O(n)。
总结推荐
推荐使用动态规划方法,因为它既避免了递归中的重复计算,又比迭代方法具有更好的可读性和模块化性。同时,动态规划方法在计算大规模斐波那契数列时具有较高的效率。