题目链接
题目描述
斐波那契数列(Fibonacci Sequence)定义如下:
- 对于
,有
给定一个正整数 (
),请你输出
的值。由于这个结果可能很大,你只需要输出这个结果对
取模后的结果即可。
解题思路
本题要求计算斐波那契数列的第 项。根据题目给出的数据范围
,我们可以选择最直观且高效的线性递推方法(也称为动态规划)。
-
算法选择
-
线性递推:由于
的最大值是
,一个从头开始计算到第
项的循环,其计算量级在
左右,这对于现代计算机来说是完全可以接受的。因此,时间复杂度为
的线性递推是本题的最佳解法。
-
矩阵快速幂:这种方法的时间复杂度为
,通常用于处理
值非常大(例如
)的情况。对于本题,
,使用矩阵快速幂虽然也能解决问题,但代码实现更复杂,属于“杀鸡用牛刀”,不是必需的。
-
-
线性递推实现
我们可以使用迭代的方式来计算
。
-
状态定义:我们只需要知道前两项就能计算出当前项。
-
初始条件:根据题目定义,
。
-
递推过程:我们从
开始循环,直到
。在每一步循环中,我们计算
。
-
空间优化:在计算
时,我们只用到了
和
。因此,我们不需要一个大小为
的数组来存储整个数列,只需要三个变量来滚动更新即可。例如,用变量
分别代表
。在每次迭代后,更新
。
-
代码
#include <iostream>
using namespace std;
const int MOD = 1000000007;
int main() {
int k;
cin >> k;
if (k == 1 || k == 2) {
cout << 1 << endl;
return 0;
}
long long a = 1;
long long b = 1;
long long c = 0;
for (int i = 3; i <= k; ++i) {
c = (a + b) % MOD;
a = b;
b = c;
}
cout << b << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
if (k == 1 || k == 2) {
System.out.println(1);
return;
}
long a = 1;
long b = 1;
long c = 0;
for (int i = 3; i <= k; i++) {
c = (a + b) % 1000000007;
a = b;
b = c;
}
System.out.println(b);
}
}
MOD = 1000000007
def main():
k = int(input())
if k == 1 or k == 2:
print(1)
return
a, b = 1, 1
for _ in range(3, k + 1):
c = (a + b) % MOD
a = b
b = c
print(b)
if __name__ == "__main__":
main()
算法及复杂度
-
算法:动态规划 / 递推
-
时间复杂度:
。我们需要一个循环从
迭代到
来计算结果。
-
空间复杂度:
。我们只使用了常数个变量来存储斐波那契数列的中间值。