题目描述:
解题思路:
可以使用循环,也可以使用递归,后者会更直观一点。
题解:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;//c++11前版本不支持
const int N = 1e5 +9;
const ll p = 1e9 +7;
//数据超过1e9时需要开long long
ll fib(int n)
{
if(n <= 2)
{
return 1;//递归出口需要用return
}
return (fib(n-1)+fib(n -2)) % p;//相同重复操作写这种模板(调用自身)
// 这里也可以写成是
// ans = (fib(n-1)+fib(n -2)) % p;
// return ans;
// 本质上都是返回除出口以外的该层的结果。
}
int main()
{
int n; cin >> n;
cout << fib(n);
return 0;
}
若将题目改为计算1~n全部,则该写法有个弊端,当数值过大时,速度慢:
优化(记忆化):采用dp[N]记录每一个节点(带备忘录的递归),将不会重复计算结点。
#include<bits/stdc++.h>
using namespace std;
using ll = long long; // c++11前版本不支持
const int N = 1e5 +9;
const ll p = 1e9 +7;
// 备忘录
ll dp [N];
//数据超过1e9时需要开long long
ll fib(int n)
{
if(n <= 2)return 1; //递归出口需要用return
if(dp[n] != -1)return dp[n]; // 调用记录过的dp[n]
return dp[n] = (fib(n-1)+fib(n -2)) % p; // 相同重复操作写这种模板(调用自身)
}
int main()
{
memset(dp, -1, sizeof dp); // 将dp数组初始化为-1,
int n; cin >> n;
cout << fib(n) << "\n";
return 0;
}
知识点:记忆化搜索,dfs