斐波那契数列求法

文章目录

  • 求斐波那切数列的几个方法:
    • 经典做法:
      • 递推:
      • 动态规划
    • 矩阵快速幂
      • 原理:
      • 代码:
      • 例题:
    • 模拟过程

求斐波那切数列的几个方法:

经典做法:

众所周知:斐波那契数列的定义是f(n + 1) = f(n) + f(n - 1)
我们有两种方式来实现:一个是递归,一个是动态规划

递推:

int dfs(int n)
{if (n == 1)return 1;if (n == 2)return 2;return dfs01(n - 1) + dfs01(n - 2);
}

动态规划

int dfs03(int n)
{vec[maxn]vec[0] = 1;vec[1] = 2;int i;for (i = 2; i < n; i++){vec[i] = vec[i - 1] + vec[i - 2];}return vec[i-1];
}

矩阵快速幂

经典做法只要数一大就会超时,我们可以用矩阵快速幂进行优化,能将时间复杂度降到O(logN)
(如果全位输出斐波那契数,貌似最大能算法到93,但是如果带mod,那就可以算很大)
常用于求第n位斐波那契数的后x位(mod 10x

原理:

快速幂+矩阵
矩阵乘法:左矩阵的第一行乘以右矩阵的第一列(分别相乘),乘完后相加
单位矩阵: nn的矩阵 mat ( i , i )=1; 任何一个矩阵乘以单位矩阵就是它本身 n单位矩阵=n, 可以把单位矩阵等价为整数1。(单位矩阵用在矩阵快速幂中)
在这里插入图片描述
在斐波那契数列中:
f[n ] = 1 * f[n-1] + 1 * f [n - 2]
f[n-1] =1 * f[n-1] +0 * f [n - 2]
我们用矩阵来表示:
在这里插入图片描述
这就表示了斐波那契数列如何用矩阵来实现。

代码:

#include <iostream>  
#include <cstddef>  
#include <cstring>  
#include <vector>  
using namespace std;  
typedef long long ll;  
const int mod=10000;  
typedef vector<ll> vec;  
typedef vector<vec> mat;  
mat mul(mat &a,mat &b) 
{  mat c(a.size(),vec(b[0].size()));  for(int i=0; i<2; i++)  {  for(int j=0; j<2; j++)  {  for(int k=0; k<2; k++)  {  c[i][j]+=a[i][k]*b[k][j];  c[i][j]%=mod;  }  }  }  return c;  
}  
mat pow(mat a,ll n)  
{  mat res(a.size(),vec(a.size()));  for(int i=0; i<a.size(); i++)  res[i][i]=1;//单位矩阵;  while(n)  {  if(n&1) res=mul(res,a);  a=mul(a,a);  n/=2;  }  return res;  
}  
ll solve(ll n)  
{  mat a(2,vec(2));  a[0][0]=1;  a[0][1]=1;  a[1][0]=1;  a[1][1]=0;  a=pow(a,n);  return a[0][1];//也可以是a[1][0];  
}  
int main()  
{  ll n;  while(cin>>n&&n!=-1)  {  cout<<solve(n)<<endl;  }  return 0;  
}  
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007;   
struct  matrix      //定义结构体矩阵
{ll x[2][2];
} ;
matrix  mul(matrix a,matrix b)     //矩阵乘法运算
{matrix ans;memset(ans.x,0,sizeof(ans.x));for(int i=0;i<2;i++)          //三个循环表示两个方阵相乘,可手动推写一遍{for(int j=0;j<2;j++){for(int k=0;k<2;k++){ans.x[i][j]+=a.x[i][k]*b.x[k][j];ans.x[i][j]%=mod;}}}return ans;
}
matrix quickpow(matrix p,ll n)    //矩阵快速幂,与快速幂道理方法相同
{matrix ans;for(int i=0;i<2;i++){for(int j=0;j<2;j++){if(i==j){ans.x[i][j]=1;}   //一开始初始化他为单位阵else ans.x[i][j]=0;}}while(n)//快速幂{if(n&1){ans=mul(ans,p);}p=mul(p,p);n>>=1;}return ans;
}
int main()
{matrix m;m={0,1,1,1};      ll n;cin>>n;ll ans1=0;matrix ans=quickpow(m,n-1);cout<<ans.x[1][1]<<endl;    return 0;  
}

例题:

POJ 3070

模拟过程

如果数很大,比如求1000的斐波那契数列,矩阵快速幂也求不出来,那咋办?
我们可以模拟斐波那契数列数列计算的过程,斐波那契数列的定义是f(n + 1) = f(n) + f(n - 1),我们可以手写加减,模拟进行加减运算
例题 大菲波数
H DU - 1715

#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef long long ll;
int main(){int n,q,i,j,temp=0;cin>>q;while(q--){cin>>n;char a[10010]="1",b[10010]="1",c[10010]={0};for(i=0;i<n-2;i++){int len=max(strlen(a),strlen(b));for(j=0;j<len;j++){   //模拟加法temp=0;if(a[j]>='0'){    //短的数不加temp+=a[j]-'0';}if(b[j]>='0'){temp+=b[j]-'0';}if(temp>=10){      //判断进位if(c[j]>='0'){c[j]+=temp-10;}else{c[j]+=temp-10+'0';}c[j+1]=1+'0';}else{if(c[j]>='0'){if(temp==9){   //若前位进位了,而且加上的数字是9,那么还要进位!!!c[j]='0';c[j+1]='1';}else{c[j]+=temp;}}else{c[j]+=temp+'0';}}}strcpy(a, b);strcpy(b, c);memset(c, 0, sizeof(c));}int len=strlen(b);for(i=len-1;i>=0;i--){  //倒着输出printf("%c",b[i]);}printf("\n");}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.Net Core2.1中的HttpClientFactory系列一

引言&#xff1a;ASP.NET Core2.1 中出现了一个新的 HttpClientFactory 功能, 它有助于解决开发人员在使用 HttpClient 实例从其应用程序中访问外部 web 资源时可能遇到的一些常见问题。关于HttpClientFactory 到底解决了那些HttpClient的严重问题&#xff0c;下面是我罗列出来…

欧拉回路哈密顿回路

欧拉回路 总结 百度百科 混合图的欧拉回路 Fleury算法 Hierholzer算法 //寻找无向图的欧拉路径 #include<iostream> #include<vector> #include<stack> using namespace std; vector<int> g[1001]; int n,m,x,y,d[1001],s-1,t-1; bool vis[1001][100…

【CDQ分治】三维偏序(luogu 3801/金牌导航 CDQ分治-1)

三维偏序 luogu 3801 金牌导航 CDQ分治-1 题目大意 有n个元素&#xff0c;第i个元素有ai,bi,cia_i,b_i,c_iai​,bi​,ci​三个属性&#xff0c;设 f(i)表示满足aj⩽aia_j\leqslant a_iaj​⩽ai​且bj⩽bib_j \leqslant b_ibj​⩽bi​且cj⩽cic_j \leqslant c_icj​⩽ci​且…

P4929-[模板]舞蹈链(DLX)

正题 题目链接:https://www.luogu.com.cn/problem/P4929 题目大意 n∗mn*mn∗m的矩形有0/10/10/1&#xff0c;要求选出若干行使得每一列有且仅有一个111。 解题思路 精确覆盖问题指的是一个集合SSS和它的若干个子集集合TTT&#xff0c;要求选出TTT的一个子集使得里面的集合元…

最大子矩阵(普通和01)

文章目录普通矩阵&#xff08;单个矩阵值为任何数&#xff09;最大子段和扩展到二维情况01矩阵&#xff08;单个矩阵值为0或1&#xff09;代码&#xff1a;普通矩阵&#xff08;单个矩阵值为任何数&#xff09; 例题&#xff1a;POJ 1074 求出其中最大的子矩阵 答案是&#x…

自动化流程开源框架BotSharp

BotSharp是一款为方便构建智能对话机器人平台而开发的开源框架&#xff0c;最大的特点是所有模型算法都是基于.NET Core开发实现&#xff0c;甚至最基本的Penn Treebank分词标准&#xff0c;都重新用C#实现了。在机器学习python占绝对优势的时代算是不可多得的项目。该项目涉及…

二分图匹配

定义&#xff1a; 二分图&#xff1a;一个图被分成了两部分&#xff0c;相同的部分没有边 匹配&#xff1a;二分图G的子图M中&#xff0c;M的边集{E}中的任意两条边都不指向同一个顶点 极大匹配&#xff1a;在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹…

【整体二分】区间第k小(金牌导航 整体二分-1)

区间第k小 金牌导航 整体二分-1 题目大意 给出一个序列&#xff0c;有若干查询&#xff0c;每次查询给出l,r,k&#xff0c;让你求l~r这个区间的第k大 输入样例 7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3输出样例 5 6 3数据范围 1⩽n⩽105,1⩽m⩽50000,1⩽∣ai∣⩽1091\leqsla…

积极参与开源项目,促进.NET Core生态社区发展

今天早上在微信群里聊天聊到百度的SDK 已经支持.NET Core, 百度已经在3月份就支持了&#xff0c;想起当时还是我在他们的github上提的issue&#xff1a; https://github.com/Baidu-AIP/dotnet-sdk/issues/3。.NET Core生态社区的发展已经四年多时间&#xff0c;日趋完善&#x…

P6091-[模板]原根

正题 题目链接:https://www.luogu.com.cn/problem/P6091 题目大意 给出一个数ppp&#xff0c;求出它的所有在[0,p][0,p][0,p]的原根。 解题思路 原根的定义&#xff0c;δp(a)\delta_p(a)δp​(a)表示一个最小的nnn使得an≡1(modp)a^n\equiv1(mod\ p)an≡1(mod p)&#xff0…

并查集小记

有什么用&#xff1a; 查询元素a和元素b是否属于同一组 合并元素a和元素b所在组 代码实现&#xff1a; #include<iostream> using namespace std; int n,m,p; int fa[5001]; int find(int x){if(fa[x]x) return x;else{return fa[x]find(fa[x]);} } int main(){cin&g…

Poj 1011 UVA - 307 Sticks

牛客网 poj 1011 题目&#xff1a; George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long th…

HAPPY2020暑假训练前复习

A.计蒜客 - T1381 输出hello world 万恶之源 B.51Nod - 2060 全排列输出 不要用STL的next_permutation,会超时 #include <bits/stdc.h> using namespace std; const int maxn14; int dt[maxn]; int vis[maxn];int n; void dfs(int depth) {if(depthn){for(int i0;; i…

【LCT】洞穴勘测(luogu 2147/金牌导航 LCT-1)

洞穴勘测 luogu 2147 金牌导航 LCT-1 题目大意 给你若干操作&#xff0c;有三种操作&#xff1a; 1.连接两个点 2.吧两个点之间的连边断掉&#xff08;保证有这条边&#xff09; 3.查询两个点之间是否连通 样例 #1 输入样例 #1 200 5 Query 123 127 Connect 123 127 Que…

Service Fabric 与Ocelot 的集成

概要云应用程序通常都需要使用前端网关&#xff0c;为用户、设备或其他应用程序提供同一个入口点。 在 Service Fabric 中&#xff0c;网关可以是任意无状态服务&#xff08;如 ASP.NET Core 应用程序&#xff09; 。本文介绍了如何将Ocelot用作 Service Fabric 应用程序的网关…

图论复习——最短路

知识点 最短路径算法 最短路径树 每个点uuu的父亲为使uuu得到最短距离的前驱节点&#xff0c;若有多个&#xff0c;则取任意一个。 题目 CF449B Jzzhu and Cities Blog CF464E The Classic Problem Blog [XSY3888] 传送门 对每个点uuu&#xff0c;记d(u)d(u)d(u)表示uuu…

Loj#143-[模板]质数判定【Miller-Rabin】

正题 题目链接:https://loj.ac/p/143 题目大意 给出一个数ppp&#xff0c;让你判定是否为质数。 解题思路 Miller−RabinMiller-RabinMiller−Rabin是一种基于费马小定理和二次探测定理的具有较高正确性的高效质数判定算法。 首先讲一下两个定理 费马小定理&#xff1a;gcd(…

【LCT】Tree II(luogu 1501)

Tree II luogu 1501 题目大意 给出一棵树&#xff0c;让你进行若干操作&#xff0c;操作如下&#xff1a; 1.把两个点路径上的所有点权值加k 2.把两个点路径上的所有点权值乘k 3.把一条边断开&#xff0c;连上另一条边 4.查询两个点路径上的权值和 输入样例 3 2 1 2 2 3 *…

图论复习汇总

三元环计数&四元环计数 Blog dfs树,点双,边双,强连通分量 Blog bfs树 对一个图运行 bfs 算法&#xff0c;每个点uuu的父亲定义为第一次遍历uuu时的前驱结点&#xff0c;若无则为根。 非树边只存在在同一层的两个点和相邻层的点中。 hihoCoder1147 时空阵 题意&#x…

P4718-[模板]Pollard-Rho算法

正题 题目链接:https://www.luogu.com.cn/problem/P4718 题目大意 给出一个数nnn&#xff0c;如果它是质数则输出PrimePrimePrime&#xff0c;否则输出它的最大质因子。 解题思路 Pollard-Rho\text{Pollard-Rho}Pollard-Rho算法的前置知识是Miller-Rabin\text{Miller-Rabin}M…