高精度斐波那契

1.为何会有高精度斐波那契一说?

 0 0
 1 1
 2 1
 3 2
 4 3
 5 5
 6 8
 7 13
 8 21
 9 34
10 55
11 89
12 144
13 233
14 377
15 610
16 987
17 1597
18 2584
19 4181
20 6765
21 10946
22 17711
23 28657
24 46368
25 75025
26 121393
27 196418
28 317811
29 514229
30 832040
31 1346269
32 2178309
33 3524578
34 5702887
35 9227465
36 14930352
37 24157817
38 39088169
39 63245986
40 102334155
41 165580141
42 267914296
43 433494437
44 701408733
45 1134903170
46 1836311903
47 2971215073
48 4807526976
49 7778742049
50 12586269025
51 20365011074
52 32951280099
53 53316291173
54 86267571272
55 139583862445
56 225851433717
57 365435296162
58 591286729879
59 956722026041
60 1548008755920
61 2504730781961
62 4052739537881
63 6557470319842
64 10610209857723
65 17167680177565
66 27777890035288
67 44945570212853
68 72723460248141
69 117669030460994
70 190392490709135
71 308061521170129
72 498454011879264
73 806515533049393
74 1304969544928657
75 2111485077978050
76 3416454622906707
77 5527939700884757
78 8944394323791464
79 14472334024676221
80 23416728348467685
81 37889062373143906
82 61305790721611591
83 99194853094755497
84 160500643816367088
85 259695496911122585
86 420196140727489673
87 679891637638612258
88 1100087778366101931
89 1779979416004714189
90 2880067194370816120
91 4660046610375530309
92 7540113804746346429
93 12200160415121876738

由上可知,斐波那契数列若在一个很大的数据范围内必然会超出数据范围,所以在做有关斐波那契数列有关的题目时要注意是否要使用高精防止超出数据范围

2.高精的引入

我们先来看一下高精度加法

for(int i=1;i<=len;i++){
    if(a[i]>9){
        a[i+1]+=a[i]/10;
        a[i]%=10;
    }
}
if(a[len+1]!=0)
    len++;

个人理解:为防止数据超出范围,利用数组来储存每一位数来进行输出,若数组某一部分大于九,则取十进一

3.高精与斐波那契的结合

long long a[2000][6666];//2000代表斐波那契数列第2000个数,6666代表的是高精度位数(防止位数不够)
for(int i=1;i<=len;i++){
    a[n][len]=a[n-1][len]+a[n-2][len];//这里是纯计算斐波那契数列,len不变,记录当下的值
}
for(int i=1;i<=len;i++){//对每一位数进行判断,如果出现大于9的数,说明需要进位
    if(a[n][len]>9){
        a[n][len+1]+=a[n][len]/10;
        a[n][len]%=10;
    }
}
if(a[n][len+1]!=0)
    len++;

4.具体题目分析

洛谷P2437蜜蜂路线

#include<bits/stdc++.h>
using namespace std;
int a[1100][1100];
int main(){
	int m,n;
	int flag=0;
	cin>>m>>n;
    a[0][1]=0;
	a[1][1]=1;
	a[2][1]=2;
	for(int i=3;i<=n-m;i++){
		for(int j=1;j<1100;j++){
			a[i][j]=a[i-1][j]+a[i-2][j];
		}
		for(int j=1;j<1100;j++){
			while(a[i][j]>9){
				a[i][j+1]++;
				a[i][j]-=10;
			}
		}
	}
	for(int i=1100;i>1;i--){
		if(a[n-m][i]==0&&!flag) continue;//特判第一位是否为零
		flag=1;
		cout<<a[n-m][i];
		
	}
	cout<<a[n-m][1]; //特判n-m=0时
	return 0;
} 
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值