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;
    }


     

  • 相关阅读:
    BroadcastReceiver之发送自定义无序广播
    BroadcastReceiver之应用卸载和安装监听
    Android几种打开SQLite的方法
    BroadcoastReceiver之短信到来监听和获取内容
    BroadcastReceiver之SD的挂载监听
    BroadcastReceive之ip拨号
    Activity之多启动图标
    Uwp Windows10获取设备位置(经纬度)
    DeviceFamily XAML Views(一)
    [SCOI2010]生成字符串
  • 原文地址:https://www.cnblogs.com/zswbky/p/5432057.html
Copyright © 2011-2022 走看看