题目描述

Winder 最近在学习 fibonacci 数列的相关知识。我们都知道 fibonacci 数列的递推公式是F(n) = F(n - 1) + F(n - 2)(n >= 2 且 n 为整数)。

Winder 想知道的是当我们将这个递推式改为F(n) = a * F(n - 1) + b * F(n - 2)(n >= 2 且 n 为整数)时我们得到的是怎样的数列。但是,Winder 很懒,所以只能由你来帮他来完成这件事。

注意,这里我们依然令 F(0)=F(1)=1。

输入格式

输入第一行三个正整数 q, a, b。

接下来有 q 行,每行一个自然数 n。

对于50%的数据,1 <= q、n <= 1000。

对于80%的数据,1 <= q、n <= 100000。

对于100%的数据,1 <= q <= 100000,1 <= n <= 1000000000,1 <= a、b <= 1000。

输出格式

输出一行一个整数 F(n),由于结果可能会很大,Winder 要求输出结果对 2013 取模,即将 F(n)对2013求余后输出。

样例输入

  1. 5 4 5
  2. 2
  3. 4
  4. 8
  5. 16
  6. 32

样例输出

  1. 9
  2. 209
  3. 1377
  4. 182
  5. 9

方法一:

刚开始拿到题目的时候第一反应是按要求做一个递归算法,但是后来发现递归的代价太大,可能会过不了。

方法二:

和方法一一个思路,但是使用了非递归算法,虽然肯定不是最优算法,但是应该可以得一个基础分了。

  1. #include <iostream>
  2. using namespace std;
  3. int fibonacci(int n, int a, int b)
  4. {
  5. if (n <= )
  6. return ;
  7. else
  8. {
  9. int current = ;
  10. int pre1 = ;
  11. int pre2 = ;
  12. for (int i = ; i <= n; i++)
  13. {
  14. current = (a * pre1 + b * pre2) % ;
  15. pre2 = pre1;
  16. pre1 = current;
  17. }
  18. return current;
  19. }
  20. }
  21. int main()
  22. {
  23. int q, a, b;
  24. cin >> q >> a >> b;
  25. int *result = new int[q];
  26. for (int i = ; i < q; i++) {
  27. int n;
  28. cin >> n;
  29. result[i] = fibonacci(n, a, b);
  30. }
  31. for (int i = ; i < q; i++) {
  32. cout << result[i] << endl;
  33. }
  34. delete[]result;
  35. return ;
  36. }

方法三:

这个是在理解了矩阵快速幂的思想基础上,进行改进的一个算法,把问题规模直接降了一大截。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <iostream>
  5. using namespace std;
  6. const int MOD = ;
  7.  
  8. struct matrix { //矩阵
  9. int m[][];
  10. }ans;
  11.  
  12. matrix multi(matrix a, matrix b) { //矩阵相乘,返回一个矩阵
  13. matrix tmp;
  14. for (int i = ; i < ; i++) {
  15. for (int j = ; j < ; j++) {
  16. tmp.m[i][j] = ;
  17. for (int k = ; k < ; k++)
  18. tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
  19. }
  20. }
  21. return tmp;
  22. }
  23.  
  24. matrix matrix_pow(matrix a, int n) { //矩阵快速幂,矩阵a的n次幂
  25. ans.m[][] = ans.m[][] = ; //初始化为单位矩阵
  26. ans.m[][] = ans.m[][] = ;
  27. while (n) {
  28. if (n & ) ans = multi(ans, a);
  29. a = multi(a, a);
  30. n >>= ;
  31. }
  32. return ans;
  33. }
  34.  
  35. int main() {
  36. int q, n, a, b;
  37. cin >> q >> a >> b;
  38. int* result = new int[q];
  39. matrix mul;
  40. mul.m[][] = a;
  41. mul.m[][] = b;
  42. mul.m[][] = ;
  43. mul.m[][] = ;
  44. for (int i = ; i < q; i++) {
  45. int n;
  46. cin >> n;
  47. matrix mm = matrix_pow(mul, n - );
  48. result[i] = (mm.m[][] + mm.m[][])%MOD;
  49. }
  50. for (int i = ; i < q; i++) {
  51. cout << result[i] << endl;
  52. }
  53. delete[]result;
  54. return ;
  55. }

第一次做的时候因为最后一步的时候在result[i] = (mm.m[0][0] + mm.m[0][1])%MOD的时候忘记

了加这个“%MOD”,导致结果一直有部分不对,调试了将近一个上午(好惨)。

算法设计与分析 1.2 不一样的fibonacci数列 (矩阵快速幂思想)的更多相关文章

  1. 算法设计与分析 1.2 不一样的fibonacci数列

    ★题目描述 fibonacci 数列的递推公式是F(n) = F(n-1) + F(n-2)(n >= 2 且 n 为整数). 将这个递推式改为F(n) = aF(n-1) + bF(n-2)( ...

  2. 2020牛客寒假算法基础集训营1 J. 缪斯的影响力 (矩阵快速幂/费马小定理降幂)

    https://ac.nowcoder.com/acm/problem/200658 f(n) = f(n-1) * f(n-2) * ab ,f的第一项是x,第二项是y. 试着推出第三项是x·y·a ...

  3. 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第7章 动态规划

    由于种种原因(看这一章间隔的时间太长,弄不清动态规划.分治.递归是什么关系),导致这章内容看了三遍才基本看懂动态规划是什么.动态规划适合解决可分阶段的组合优化问题,但它又不同于贪心算法,动态规划所解决 ...

  4. 算法设计与分析 - AC 题目 - 第 5 弹(重复第 2 弹)

    PTA-算法设计与分析-AC原题 - 最大子列和问题 (20分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+, ..., Nj },其中 ≤i ...

  5. 算法设计与分析 - AC 题目 - 第 2 弹

    PTA-算法设计与分析-AC原题7-1 最大子列和问题 (20分)给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1 ...

  6. 算法设计与分析-Week12

    题目描述 You are given coins of different denominations and a total amount of money amount. Write a func ...

  7. 【BZOJ1009】GT考试(KMP算法,矩阵快速幂,动态规划)

    [BZOJ1009]GT考试(KMP算法,矩阵快速幂,动态规划) 题面 BZOJ 题解 看到这个题目 化简一下题意 长度为\(n\)的,由\(0-9\)组成的字符串中 不含串\(s\)的串的数量有几个 ...

  8. 整数快速乘法/快速幂+矩阵快速幂+Strassen算法

    快速幂算法可以说是ACM一类竞赛中必不可少,并且也是非常基础的一类算法,鉴于我一直学的比较零散,所以今天用这个帖子总结一下 快速乘法通常有两类应用:一.整数的运算,计算(a*b) mod c  二.矩 ...

  9. FZU2018级算法第一次作业 1.1fibonacci (矩阵快速幂)

    题目 Winder最近在学习fibonacci 数列的相关知识.我们都知道fibonacci数列的递推公式是F(n)=F(n-1)+F(n-2)(n>=2 且n 为整数). Winder想知道的 ...

随机推荐

  1. opencv中对图片的二值化操作并提取特定颜色区域

    一.最近因为所在的实习公司要求用opencv视觉库来写一个对图片识别并提取指定区域的程序.看了很多资料,只学会了皮毛,下面附上简单的代码.运行程序之前需要安装opencv库,官网地址为:https:/ ...

  2. Android 子线程无法刷新UI界面

    问题:在Android开发中,子线程无法直接更改UI界面视图的刷新 这个时候 Handler 起到了至关重要的作用. 简单来说 , Handler就是用来传递消息的. Handler可以当成子线程与主 ...

  3. C++中的异常处理(上)

    1,C++ 内置了异常处理的语法元素 try ... catch ...: 1,try 语句处理正常代码逻辑: 2,catch 语句处理异常情况: 3,try 语句中的异常由对应的 catch 语句处 ...

  4. 从入门到自闭之Python 基础习题训练

    """ name = input(">>>")通过代码来验证name变量是什么数据类型? """ na ...

  5. xcode中进行git代码管理

    http://www.cocoachina.com/ios/20140524/8536.html

  6. 2019-11-29-VisualStudio-使用新项目格式快速打出-Nuget-包

    title author date CreateTime categories VisualStudio 使用新项目格式快速打出 Nuget 包 lindexi 2019-11-29 10:15:25 ...

  7. Windows PyCharm QtDesigner/pyuic5配置

    QtDesigner 配置成功截图如下: C:\ProgramData\Anaconda3\Library\bin\designer.exe $FileDir$ pyuic5 配置成功截图如下: C: ...

  8. Laravel 向公共模板赋值

    开发过程中许多时候都会向公共模板赋值,比如顶部导航栏,页面底部等等,不可能在每个控制器中都赋值一遍. Laravel 中解决办法如下:修改 App\Providers\AppServiceProvid ...

  9. AIX中的页空间管理

    1.页空间简介(Paging  Space) 页空间是指硬盘上的存储内存信息的区域. 一个页空间也叫做一个交换空间. 是系统中一个类型为paging的逻辑卷.       2.创建页空间 使用mkps ...

  10. docker 安装与使用的相关问题

    Error response from daemon: i/o timeout $ sudo docker search centos Error response from daemon: Get ...