HLG 1126 Final Destination II

本文介绍了一种解决特定递归问题的方法——通过优化递推公式利用矩阵乘方来减少计算复杂度。该方法适用于求解n级台阶的不同走法数量问题,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

你每次可以上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

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

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

矩阵乘方

http://blog.youkuaiyun.com/masked__dance/article/details/40351293

具体的矩阵乘方分析请看链接:

/**本题为递推公式的优化**/
#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:\n",k);
        switch(n){
        case 0:printf("1\n");break;
        case 1:printf("1\n");break;
        case 2:printf("2\n");break;
        case 3:printf("4\n");break;
        default:printf("%lld\n",quickPow(n-3,co,stairs));break;///注意这里的n-3
        }
       /* if(n==0)
            printf("1\n");
        else if(n == 1)
            printf("1\n");
        else if(n == 2)
            printf("2\n");
        else
            printf("%lld\n",quickPow(n-3,co,stairs));*/

    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值