• 洛谷P1192 台阶问题


    题目链接:https://www.luogu.org/problem/P1192

    设a[i]为走到第i阶的方法数

    假设最多可以走k步,对任意x(x>=k)容易知道

    1.a[x]=a[x-1]+a[x-2]+…+a[x-k]

    2.a[x+1]=a[x]+a[x-1]+a[x-2]+…+a[x+1-k]=2*a[x]-a[x-k]

    所以我们只需要先求出a[1]a[k]然后剩下的a[k+1]a[n]就可以直接通过上面的2式通过一次运算直接算出了 因为当数据比较大的时候k<<n,这时候复杂度近似为O(n)

    至于a[1]~a[k]可以用一下方法求出

        void init(){
            a[0]=1;   //a[0]表示走到第0阶(即起点)的方法数很容易理解为1
            for(register int i=0;i<k;i++)
            //从起点开始,访问每一阶级,假设当前访问的是第i阶,那么a[i+1]~a[i+k]要加上a[i],很容易理解
              for(register int j=1;j<=k;j++) a[i+j]=(a[i+j]+a[i])%100003;
            //可能会改变a[x](x>k)的值,但是没有影响,因为接下来是直接给a[k+1]~a[n]赋值的,所以会覆盖掉
        }
        
        //实际上对于a[1]~a[k],a[i](1<=i<=k)为2的(i-1)次方
        //至于为什么大家可以根据我上面的init()函数带入几个k写一写很容易就懂了
    

    以下是完整代码

    #include <cstdio>
    int n,k,a[100005];
    void init(){
        a[0]=a[1]=1;
        for(register int i=2;i<=k;i++)
            a[i]=(2*a[i-1])%100003;
    }
    int main(){
        scanf("%d %d",&n,&k);
        init();
        for(register int i=k+1;i<=n;i++) a[i]=(2*a[i-1]+100003-a[i-1-k])%100003;
        printf("%d
    ",a[n]);
        return 0;
    }
    
  • 相关阅读:
    [Windows Powershell]-学习笔记(1)
    MyBatis For .NET学习-问题总结
    Zynq学习笔记(1)
    规范的位操作方法
    浮点数转换成字符串函数
    测试卡尔曼滤波器(Kalman Filter)
    关于按键扫描程序的终极讨论
    关于STM8的用户数据空间读写问题
    IPv4分析
    关于STM8空间不足的解决方法
  • 原文地址:https://www.cnblogs.com/yonglin1998/p/11780812.html
Copyright © 2020-2023  润新知