zoukankan      html  css  js  c++  java
  • poj 3070 矩阵计算Fibonacci

    地址 http://poj.org/problem?id=3070

    大意是输入一个数字 输出位于Fibonacci数列该位置的数字模10000的结果

    由于n比较大 0 ≤ n ≤ 1,000,000,000 所以开数组是不可能了 只能实时计算

    使用矩阵可以加速Fibonacci数列的推导

    经过精心设置的矩阵相乘是可以从Fn-1 Fn-2推导出Fn的

    那么设置好的矩阵的多次相乘是不是就可以从F0  F1推到出Fn呢?

    是的 如图 

    1 1

    1 0 矩阵为A那么

    A^(n-1) 与F1 F0矩阵的乘法就是可以推到出 Fn

    代码借用了之前的快速幂代码 不是模板 所以虽然可以AC但是代码复用性不好 先学理论 板子日后再找

     1 #include <iostream>
     2 #include <vector>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 
     7 struct matrix {
     8     int data[35][35];
     9 };
    10 
    11 int n = 2;
    12 int m = 10000;
    13 int k = 0;
    14 
    15 //矩阵乘法
    16 matrix mul(matrix a, matrix b)
    17 {
    18     matrix c;
    19     memset(c.data, 0, sizeof(c.data));
    20     for (int i = 1; i <= n; i++) {
    21         for (int j = 1; j <= n; j++) {
    22             for (int k = 1; k <= n; k++) {
    23                 c.data[i][j] = (c.data[i][j] + 1ll * a.data[i][k] * b.data[k][j]) % m;
    24             }
    25         }
    26     }
    27 
    28     return c;
    29 }
    30 
    31 //矩阵加法
    32 matrix add(matrix a, matrix b) {
    33     for (int i = 1; i <= n; i++) {
    34         for (int j = 1; j <= n; j++) {
    35             a.data[i][j] = (a.data[i][j] + b.data[i][j]) % m;
    36         }
    37     }
    38     return a;
    39 }
    40 
    41 //矩阵快速幂
    42 matrix quickpow(matrix a, int k) {
    43     matrix  c;
    44     memset(c.data, 0, sizeof(c.data));
    45     for (int i = 1; i <= n; i++)
    46         c.data[i][i] = 1;
    47     while (k) {
    48         if (k & 1) c = mul(c, a);
    49         k >>= 1;
    50         a = mul(a, a);
    51     }
    52     return c;
    53 }
    54 
    55 
    56 int main()
    57 {
    58     int j;
    59     while (1) {
    60         cin >> j;
    61         if (j == -1) break;
    62         if (j == 0) {
    63             cout << 0 << endl; continue;
    64         }
    65         if (j == 1 || j == 2) {
    66             cout << 1 << endl; continue;
    67         }
    68         matrix  base;
    69         base.data[1][1] = 1; base.data[1][2] = 1;
    70         base.data[2][1] = 1; base.data[2][2] = 0;
    71 
    72         matrix fn;
    73         fn.data[1][1] = 1;
    74         fn.data[2][1] = 0;
    75 
    76         matrix baseN = quickpow(base, j-1);
    77 
    78         matrix c;
    79         memset(c.data, 0, sizeof(c.data));
    80 
    81         for (int i = 1; i <= 2; i++) {
    82             for (int j = 1; j <= 1; j++) {
    83                 for(int k =1;k<=2;k++){
    84                     c.data[i][j] = (c.data[i][j] + 1ll * baseN.data[i][k] * fn.data[k][j]) % m;
    85                 }
    86             }
    87         }
    88         cout << c.data[1][1] << endl;
    89     }
    90     return 0;
    91 }
    ac code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    easyui datagrid fit 属性
    jQuery outerHeight() 方法
    从文件夹输入数据到控制台程序 c方式
    排序算法
    泛型算法
    string、char[]、char*、const char* 相互转换
    sizeof
    容器 forward_list
    sort
    printf & sprintf
  • 原文地址:https://www.cnblogs.com/itdef/p/11990278.html
Copyright © 2011-2022 走看看