斐波那契数列

斐波那契数列(Fibonacci sequence)

又称黄金分割数列,因数学家莱昂纳多·斐波那契(LeonardodaFibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义: F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

非递归

循环迭代算法

#include<iostream>
using namespace std;

int main(){

    int a = 0,b=1;

    int n;      
    cin >> n;

    while(n--){
        cout << a << ' ';

        int t = a;  //把a给一个盒子 
        a = b;      //把b给a 
        b = t + b;  //让b做加法,传给a,输出a,t的作用是存之前的a给b计算 
    }

    return 0;
}

递归算法

在这里插入图片描述

#include<iostream>
using namespace std;

int f(int n){
	if(n==0) return 0;
    else if(n <= 2) return 1;
    else return (f(n-2) + f(n-1);
}
int main(){
    int n ;
    cin >> n;

    cout << f(n) << endl;

    return 0;
}

由于每次递归都需要重复计算很多数字所以需要改进——记忆化搜索
开一个大数组记录中间的结果,如果算过了的话就查表,没算过就算一遍(递归层数太多容易爆栈)

#include<iostream>
using namespace std;

const int N = 1000000;
int a[N];
int f(int n){
	if(a[n]) return a[n];
	if(n==0) return 0;
	if(n==1) return 1;
	a[n] = f(n-1)+f(n-2);

	return a[n];
}
int main(){
	
	int n;
	cin >> n;
	cout << f(n);
	return 0;
} 

快速幂

在这里插入图片描述

#include<iostream>
using namespace std;

long long fastPower(long long base,long long power){
	long long result = 1;
	while(power > 0){			
		if(power%2 == 0){		 //如果指数是偶数 
			power = power / 2;	 //指数减半 
			base = base * base;	 //底数平方 
		}
		else{					//指数是奇数 
			power = power - 1;	//指数减一 
			result = result * base;	//结果把刚才减去的底数乘进去 
			power = power / 2;	//减一变偶数了嘛跟上面一样 
			base = base * base;
		}
	}
	return result;
} 
int main(){
	
	long long n,m;
	cin >> n;
	cin >> m;
	cout << fastPower(n,m);
	
	return 0;
}

对于上述代码我们还可以优化一下 power = power - 1; power = power / 2;
这两句话我们能否做一下优化呢?
我们知道power是一个整数,当他是奇数的时候如5/2=2;和5-1=4,4/2=2结果一样,所以我们可以再优化一下代码。

#include<iostream>
using namespace std;

long long fastPower(long long base,long long power){
	long long result = 1;
	while(power > 0){			
		if(power%2 == 1)			//如果是奇数 
			result = result * base;	//结果先乘一下底数 
			
		power = power / 2;			//指数除二	
		base = base * base;			//底数平方 
	}
	return result;
} 
int main(){
	
	long long n,m;
	cin >> n;
	cin >> m;
	cout << fastPower(n,m);
	
	return 0;
}

对于这个代码还有一个最最最终极的优化 这里运用到了位运算。
计算机中的所有数据都是以二进制的形式存储在设备中,即0、1两种状态,合理利用位运算可以更显著的提高代码的执行效率。

&两个位都为1时,结果才为1
|两个位都为0时,结果才为0
^异或两个位相同为0,相异为1
~取反0变1,1变0
<<左移各二进位全部左移若干位,高位丢弃,低位补0
>>右移各二进位全部右移若干位,对无符号数,高位补0,有符号数编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

power%2==1可以用更快的“位运算”来代替,例如:power&1。因为如果power为偶数,则其二进制表示的最后一位一定是0;如果power是奇数,则其二进制表示的最后一位一定是1。将他们分别与1的二进制做“与”运算,得到的就是power二进制最后一位的数字了,是0则为偶数,是1则为奇数。例如5是奇数,则5&1=1;而6是偶数,则6&1=0;因此奇偶数的判断就可以用“位运算”来替换了。

在这里插入图片描述
所以power=power/2;可以用power>>1;代替


long long fastPower(long long base, long long power) {
    long long result = 1;
    while (power > 0) {
        if (power & 1) {//此处等价于if(power%2==1)
            result = result * base ;
        }
        power >>= 1;//此处等价于power=power/2
        base = base * base;
    }
    return result;
}

定义

在这里插入图片描述

#include <stdio.h>
#include <math.h>
int function( int i );

int main()
{
    int N;
    scanf( "%d", &N );
    
    for ( int i = 1; i <= N - 1; i++ )
        printf( "%d ", function( i ) );
    printf( "%d", function( N ) );
    return(0);
}

int function( int i )
{
    double sqrt_five = sqrt( 5.0 );
    double pow1 = pow( ( (1.0 + sqrt( 5.0 ) ) / 2.0), i );
    double pow2 = pow( ( (1.0 - sqrt( 5.0 ) ) / 2.0), i );
    int number = 1.0 / sqrt_five * (pow1 - pow2);
    return(number);
}

快速幂加大数存储

快速幂加矩阵

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值