Description
WZ是个蛋痛的人,总是喜欢琢磨蛋痛的事,比如他最近想知道上楼梯总共有多少种方式。已知他一步可以迈一阶、两阶或者三阶,现在给你楼梯的阶数,让你计算总共有多少种方式。
Input
输入有多组数据,每组数据占一行,表示楼梯的阶数。(1<=N<=100,000,000,000)
Output
对于每组数据,输出一行,表示上楼方式的总数 % 1000000007。
Sample Input
1
2
Sample Output
1
2
首先:递推公式:dp[i] = dp[i-1] + dp[i-2] + dp[i-3];由于这里数据太大,所以用 了矩阵快速幂,,,
参考师哥博客:
SDNU1085.爬楼梯再加强版(矩阵快速幂+矩阵关系推导)
虽然感觉把图很丑,但是,还是可以 简单理解的。。
#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 10005
#define INF 0x3f3f3f3f//将近int类型最大数的一半,而且乘2不会爆int
#define MOD 1000000007
struct node{
ll m[3][3];
}stu;
node mul(node a, node b)
{
node tem;
memset(tem.m, 0, sizeof(tem.m));
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
for (int k = 0; k < 3; ++k)
tem.m[i][j] = (tem.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
return tem;
}
node qaq(node ans, ll b)
{
memset(stu.m, 0, sizeof(stu.m));
stu.m[0][0] = stu.m[1][1] = stu.m[2][2] = 1; //单位矩阵
while (b) {
if (b & 1)
stu = mul(stu, ans);
ans = mul(ans, ans);
b >>= 1;
}
return stu;
}
int main()
{
ll n;
while (cin >> n) {
node cf;
memset(cf.m, 0, sizeof(cf.m));
cf.m[0][0] = cf.m[0][1] = cf.m[0][2] = cf.m[1][0] = cf.m[2][1] = 1;
if (n == 1) puts("1");
else if (n == 2) puts("2");
else if (n == 3) puts("3");
else {
cf = qaq(cf, n - 3);
cout << (4 * cf.m[0][0] + 2 * cf.m[0][1] + cf.m[0][2]) % MOD << '\n';
}
}
return 0;
}