超级蛙跳
Description
有一个超级运动员利用台阶练习蛙跳,每次可以跳一阶、二阶或者三阶,求该运动员跳上n阶的台阶,可能有多少种跳法。
Input
一个正整数n(1<=n<=1E18)表示台阶的阶数。
Output
一个非负整数,表示该运动员跳上n阶台阶的跳法对2021取模的结果。
Sample Input 1
1
Sample Output 1
1
Sample Input 2
2
Sample Output 2
2
Sample Input 3
3
Sample Output 3
4
为了优化dp,采用了矩阵的快速幂算法。
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
typedef long long ll;
const ll maxn = 1e18 + 10;
const int mod = 2021;
struct Mat {
ll m[3][3];
}ans,res;//ans为结果矩阵,a为输入矩阵
Mat Mul(Mat a, Mat b, int n) {//计算矩阵a乘矩阵b,n为矩阵的大小
Mat c;//临时矩阵c
memset(c.m, 0, sizeof(c.m));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
c.m[i][j] = (c.m[i][j] + (a.m[i][k] * b.m[k][j]) % mod) % mod;
return c;
}
Mat _power(Mat a, ll b, int n) {//计算a^b,n为矩阵的大小
for (int i = 0; i < n; i++)//构造单位矩阵
res.m[i][i] = 1;
while (b) {
if (b & 1)
res = Mul(res, a, n);
a = Mul(a, a, n);
b >>= 1;
}
return res;
}
int main()
{
ll N;
scanf("%ld", &N);
if (N == 1 || N == 2 || N == 3){
if (N == 1) printf("1");
else if (N == 2)printf("2");
else if (N == 3)printf("4");
return 0;
}
else
{
ans.m[0][0] = 1;
ans.m[0][1] = 1;
ans.m[0][2] = 1;
ans.m[1][0] = 1;
ans.m[1][1] = 0;
ans.m[1][2] = 0;
ans.m[2][0] = 0;
ans.m[2][1] = 1;
ans.m[2][2] = 0;
Mat result = _power(ans, N - 3, 3);
ll Out = (((result.m[0][0] * 4) % mod + (result.m[0][1] * 2) % mod) % mod + (result.m[0][2] * 1)) % mod;
printf("%ld", Out);
return 0;
}
}