楼梯问题

  楼梯问题

题目描述

有一段长为n的阶梯,最多可以往上跨k步,请求出走到第n级阶梯的总方案数mod 7777777的值。

输入

两个正整数n,k(n<=2^31-1,k<=10)

输出

总方案数 mod 7777777的值

样例输入

4
2

样例输出

5

提示

暴力是行不通的

代码

#include<cstdio>
#include<cstring>
using namespace std; 

const int mi[11] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}, Mod = 7777777; 
long long n; 
int k; 

struct matrix {
    long long m[11][11]; 
}A, B;

matrix mult(matrix a, matrix b) {
    long long sums = 0; 
    matrix c; 
    memset(c.m, 0, sizeof(c.m)); 
    for (int i = 0; i < k; i++) {
        for (int j = 0; j < k; j++) {
            sums = 0; 
            for (int w = 0; w < k; w++) {
                sums = (sums + a.m[i][w] * b.m[w][j]) % Mod; 
            }
            c.m[i][j] = sums; 
        }
    }
    return c;
}

matrix qpow(matrix a, long long t) {
    matrix res; 
    memset(res.m, 0, sizeof(res.m)); 
    for (int i = 0; i < k; i++) {
        res.m[i][i] = 1; 
    }
    while (t) {
        if (t & 1) {
            res = mult(res, a); 
        }
        t >>= 1; 
        a = mult(a, a); 
    }
    return res; 
}

int main() {
    scanf("%lld%d", &n, &k); 
    if (k <= 0) {
        printf("0"); 
        return 0; 
    }
    if (n == 1) {
        printf("1");
        return 0; 
    }
    for (int i = 0; i < k - 1; i++) {
        A.m[i][i + 1] = 1; 
    }
    for (int i = 0; i < k; i++) {
        A.m[k - 1][i] = 1; 
    }
    for (int i = 0; i < k; i++) {
        B.m[i][0] = mi[i]; 
    }
    if (n < k) {
        printf("%lld", B.m[n - 1][0]);
        return 0; 
    }
    A = qpow(A, n - k); 
    A = mult(A, B); 
    printf("%lld", A.m[k - 1][0]); 
    return 0; 
}
原文地址:https://www.cnblogs.com/GldHkkowo/p/8832212.html