楼梯问题
楼梯问题
题目描述
有一段长为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; }