zoukankan      html  css  js  c++  java
  • 斐波那契数列 Library

    http://acm.tju.edu.cn/toj/showp3267.html
    3267.   Library
    Time Limit: 1.0 Seconds   Memory Limit: 65536K
    Total Runs: 214   Accepted Runs: 96



    Description

    As we all know, there are very long stairs before our library in campus III of our school. It is so tired for us to go up stairs. Alpc60 has to go up and down stairs every day, what a boring walk!

    One day when alpc60 went up stairs, he thought that every time he can step over one or two stairs, if there are n stairs, then how many ways he can reach the top?

    The clever ACMers, can you help alpc60 to calculate how many ways he can go up n (1 ≤ n ≤ 1,000,000,000) stairs.

    Because the number of the answer will be so large, you must output the number module by 9901.

    Input

    Each line of the input contains a number n indicating the stairs number.

    Input is ended with -1 which is not the stairs number.

    Output

    For each case of the input output the possible ways module by 9901.

    Sample Input

    1
    2
    5
    -1
    

    Sample Output

    1
    2
    8
    
    Hint: The Bruce force method will simply lead to the Time Limit Exceeded error, try some efficient method to solve this problem.



    Source: NUDT Programming Contest 2009

    题意 : 上楼梯, 每次都可以上1节或2节,求有几种上楼方式,是一个典型的斐波那契数列,某状态可以是从两种情况来的,1,上两节到这儿,2,上1节到这儿,就是f[n] = f[n-1]+f[n-2]

    但是因为数会很大所以要用到矩阵,和快速矩阵幂

      1 /*
      2   快速幂矩阵法
      3   dp 动态规划
      4   a[n] = a[n-1]+ a[n-2];  这是一个典型的斐波那契数列  一般斐波那契数列算到20的时候已经很大了所以一般来说要用快速法 
      5   构造矩阵有
      6   a[n-1] = q[n-1];  为了构造一个矩阵 
      7   上下两式分析有  [ a[n]   ] = [1,1]*[a[n-1]]
      8                 [ a[n-1] ] = [1,0] [a[n-2]]
      9   其中要自定义矩阵的乘法 
     10   然后递推得  转化成求矩阵幂的问题
     11 */
     12    
     13 #include<cstdio>
     14 #include<cmath>
     15 #define N 9901 
     16 using namespace std;
     17 struct mtx{
     18 //    int n;// 矩阵的阶数
     19     int a[2][2];
     20     mtx operator * (const mtx o) const {
     21         mtx c;
     22 //        return c.n = n ;
     23     c.a[0][0]= c.a[0][1] = c.a[1][0] = c.a[1][1] = 0;//做乘法前初始化 
     24         for(int i = 0 ; i < 2 ; i++ )
     25         {
     26             for(int j = 0 ; j < 2 ; j++)
     27             {
     28                 for(int k = 0 ; k < 2 ; k++)
     29                 {
     30                     c.a[i][j] += ((a[i][k]%N)*(o.a[k][j]%N))%N;
     31                     c.a[i][j] %= N;
     32                 }
     33             }
     34         }
     35         return c;
     36     } 
     37 };//定义矩阵乘法
     38 /*  如果 递归的写数幂是  
     39 int f(int a ,int b)
     40 {
     41     int ret = 1;
     42     if (b == 1 ) return a;
     43     int t = f(a,b/2)
     44     t = t*t;
     45     if(b&1)  return t*a;
     46     return  t;
     47 }
     48 
     49 但是矩阵的乘法一般不写递归形式,因为递归用栈来存储,会爆内存 
     50 
     51 非递归形式写数幂 
     52 
     53 int f (int a , int b) 
     54 {
     55     int ret = 1;
     56     while(b > 0) 
     57     {
     58         if(b&1) ret *= a;
     59         a *= a;    
     60         b >>= 1;
     61     }
     62     return ret;
     63 } 
     64 int f(int a ,int b )
     65 {
     66     int ret;
     67     for( ret = 1 ; b ; b>>=1)
     68     {
     69         if(b&1) ret*=a;
     70         a = a * a; 
     71     }
     72     return ret;
     73 }
     74 
     75 int f (int a , int b)
     76 {
     77     int ret ;
     78     for(ret = 1 ; b ; b>>=1 , a = a * a %Mod) 
     79     if(b&1) ret = ret*a%N;////+=要比加快。。。。。也可以写成ret*=a;  ret %=a;
     80     return ret; 
     81 }
     82 */
     83 
     84 mtx f(int b)
     85 {
     86     mtx t;
     87     mtx haha ;
     88     haha.a[0][0] = haha.a[0][1] = haha.a[1][0] = 1;
     89     haha.a[1][1] = 0;
     90     
     91     t.a[0][1] = t.a[1][0] = 0;
     92     t.a[1][1] = t.a[0][0] = 1; 
     93     mtx ret ;
     94     //if(b==1)  return t;
     95     for(ret = t ; b ; b>>=1)
     96     {
     97 //    printf("%d
    ", b);
     98         if(b&1) ret = ret * haha ;
     99         haha = haha * haha; 
    100     } 
    101     return ret;
    102 } //快速幂矩阵 
    103 
    104 
    105 int main()
    106 {
    107     int cnt ; 
    108     while(~scanf("%d",&cnt)&&cnt!=-1)
    109     {
    110         mtx ans;
    111         ans = f(cnt-1);
    112     //    printf("%d %d
    %d %d
    ", ans.a[0][0], ans.a[0][1], ans.a[1][0], ans.a[1][1]); 
    113         int sum = (1*ans.a[0][0]+1*ans.a[0][1])%N;
    114         printf("%d
    ",sum);
    115     } 
    116     return 0 ;
    117 } 
  • 相关阅读:
    h5页面页面在iphoneX手机上底部会有留白解决办法
    自定义单张图片放大预览功能,可支持手势缩放,依赖jquery
    js事件内部有click事件时,click事件会重复调用解决方法
    h5页面通过阿里云的broswer-js-sdk上传文件
    python字符串前加r、f、u、l 的区别
    Python基础面试题 :计算列表中出现最多次的字符
    python基础入门教程:传参是传值还是传引用
    Python 面试题:输入一个数组,输出该数组的第二大的数字
    Python 7种超实用的数据清洗方法,这你一定要掌握
    python教程:3个非常有用的内置函数(filter/map/reduce)
  • 原文地址:https://www.cnblogs.com/shanyr/p/4657121.html
Copyright © 2011-2022 走看看