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 } 
  • 相关阅读:
    yarn 集群任务全部pending 事件记录
    flink 在使用upsert_kafka connector 时报错,找不到类Exeption: Could not find any factory for identifier 'upsert-kafka' that implements 'org.apache.flink.table.factories.DynamicTableFactory' in the classpath.
    SpringBoot 项目无法启动,且无任何日志
    Python之PyQt编程
    转:redis 节约内存之Instagram的Redis实践
    云计算 私有云 公有云 混合云
    java 类继承估计99%的人都不知道的问题?
    Java Vector 类
    Java LinkedList 类
    Java Queue 接口
  • 原文地址:https://www.cnblogs.com/shanyr/p/4657121.html
Copyright © 2011-2022 走看看