zoukankan      html  css  js  c++  java
  • HLG 1126 Final Destination II (转化为矩阵)(水题)

    题目很水,但是思想很重要

     

    是递推啊......是递推啊......

    没错真的是非常简单的递推,你没有判断错误!

    你每次可以上1个台阶,上2个台阶,上3个台阶,给出n级台阶。问你有几种走法?

    我强迫症范的时候,会一次上一个台阶,走错了,会重新走一遍敲打

    那么递推公式非常简单的出来了:

    an=an-1+an-2+an-3

    当n=1的时候为1,当n=2的时候为2,当n=3的时候为4;

    即a[1]=1,a[2]=2,a[3]=4;

    当n的时候,将规模缩小到n-1,即最后一步走一个台阶,那么有a[n-1]种方法;

    若最后一次走两个台阶,那么有a[n-2]种方法,最后一次走三个台阶,那么有a[n-3]种方法。

    递推公式就这么出来了微笑

    一般情况,我们都会使用数组存储,一次性算完,然后直接输出。显然,n的规模10^9

    显然数组是做不到的。若是循环算的话,那时间想想也是醉了。

    因此这里引入了一个新的方法,优化递推公式(应该只适用于一阶方程):

    /**本题为递推公式的优化**/
    #include <iostream>
    using namespace std;
    #include <stdio.h>
    #include <string.h>
    #define mod 1000000007
    ///递推公式为an=an-1+an-2+an-3
    void mul(long long a[][3],long long b[][3])
    {
        long long c[3][3];
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++){
                c[i][j]=0;
                for(int k=0;k<3;k++)
                    c[i][j]+=((a[i][k]%mod)*(b[k][j]%mod))%mod;
            }
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                b[i][j]=c[i][j]%mod;
    }
    long long quickPow(long long n,long long a[][3],long long b[][3])
    {
        while(n)
        {
            if(n&1)
                mul(a,b);
            n=n>>1;
            mul(a,a);
        }
        return b[0][0];
    }
    int main()
    {
        long long T,k,n;
        scanf("%lld",&T);
        for(k=1;k<=T;k++)
        {
            scanf("%lld",&n);
            long long stairs[3][3]={4,0,0,2,0,0,1,0,0};///初始化更新还有什么清空的都要注意
            long long co[3][3]={1,1,1,1,0,0,0,1,0};
            printf("Case %lld:
    ",k);
            switch(n){
            case 0:printf("1
    ");break;
            case 1:printf("1
    ");break;
            case 2:printf("2
    ");break;
            case 3:printf("4
    ");break;
            default:printf("%lld
    ",quickPow(n-3,co,stairs));break;///注意这里的n-3
            }
           /* if(n==0)
                printf("1
    ");
            else if(n == 1)
                printf("1
    ");
            else if(n == 2)
                printf("2
    ");
            else
                printf("%lld
    ",quickPow(n-3,co,stairs));*/
    
        }
        return 0;
    }


     

  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/zswbky/p/5432057.html
Copyright © 2011-2022 走看看