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 } 
  • 相关阅读:
    JQuery Ajax调用asp.net后台方法
    擦亮自己的眼睛去看SQLServer之简单Insert
    擦亮自己的眼睛去看SQLServer之简单Select
    SQL Server CONVERT() 函数
    给reporting services加个条件型的格式 (轉)
    优化SQL语句:in 和not in的替代方案
    技术不如你,但老板就是赏识他,为什么?
    LINQ to SQL活学活用(1):这要打破旧观念(轉)
    [续] MATLAB 混合编程——下篇:调用其它编程语言
    [精] MATLAB 混合编程——上篇:被其它编程语言调用
  • 原文地址:https://www.cnblogs.com/shanyr/p/4657121.html
Copyright © 2011-2022 走看看