HihoCoder1143 骨牌覆盖问题·一(矩阵快速幂,斐波那契)

来源:互联网 发布:手机淘宝差评怎么删掉 编辑:程序博客网 时间:2024/06/07 01:13

题目:

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

骨牌,一种古老的玩具。今天我们要研究的是骨牌的覆盖问题:
我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘。对于这个棋盘,一共有多少种不同的覆盖方法呢?
举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式:

提示:骨牌覆盖

提示:如何快速计算结果

输入

第1行:1个整数N。表示棋盘长度。1≤N≤100,000,000

输出

第1行:1个整数,表示覆盖方案数 MOD 19999997

样例输入
62247088
样例输出
17748018
思路:

官方讲的很详细,我直接贴上来



代码:

#include <cstdio>#include <cstring>#include <cctype>#include <string>#include <set>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 1000007#define N 2#define M 19999997#define ll long longusing namespace std;struct Matrix{long long a[2][2];Matrix(){memset(a, 0, sizeof(a));}Matrix operator * (const Matrix y){Matrix ans;for(int i = 0; i <= 1; i++)for(int j = 0; j <= 1; j++)for(int k = 0; k <= 1; k++)ans.a[i][j] += a[i][k]*y.a[k][j];for(int i = 0; i <= 1; i++)for(int j = 0; j <= 1; j++)ans.a[i][j] %= M;return ans;}void operator = (const Matrix b){for(int i = 0; i <= 1; i++)for(int j = 0; j <= 1; j++)a[i][j] = b.a[i][j];}};int solve(long long x){Matrix ans, trs;ans.a[0][0] = ans.a[1][1] = 1;trs.a[0][0] = trs.a[1][0] = trs.a[0][1] = 1;while(x){if(x&1)ans = ans*trs;trs = trs*trs;x >>= 1;}return ans.a[0][0];}int main(){int n;while(~scanf("%d", &n)){printf("%d\n",solve(n));}return 0;}


阅读全文
0 0
原创粉丝点击