题目
Description
问题描述:有2×n的一个长方形棋盘,用一些1×2的骨牌铺满方格.
例如:n=3时,在2×3的棋盘上用1×2的骨牌覆盖,共有3种铺法。
问题求解:编写一个程序,试对给出的任意一个n(n>0),输出铺法总数.Input
输入包括多组数据,每组数据占一行,且只有一个整数n (0<=n<=42),表示2*n的棋盘,当n=0时表示输入结束。
Output
输出一行结果,为一个整数,表示棋盘完美覆盖方案数。
Sample Input
8
0Sample Output
34
题解
显然,这道题可以使用某种神奇的数学规律来求解
先找下规律
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
num | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 |
就是斐波那契数列
f[n] = f[n-1] + f[n-2]
理解下原理
最后的方块只有两种情况:
- 竖着放一列
- 横着两个放两列
分别对应
- 最后两列一个竖着放,考虑前面
n-1
列的情况(f[n-1]
) - 最后两列全部竖着放,考虑前面
n-2
列的情况(f[n-2]
)
因此,将两种情况加起来就是答案
代码
/* By:OhYee Github:OhYee HomePage:http://www.oyohyee.com Email:oyohyee@oyohyee.com Blog:http://www.cnblogs.com/ohyee/ かしこいかわいい? エリーチカ! 要写出来Хорошо的代码哦~ */ #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> using namespace std; const int maxn = 45; int f[maxn] = {1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,165580141,267914296,433494437,701408733,1134903170}; void F(int i=2) { if(i == maxn) return; f[i] = f[i - 1] + f[i - 2]; F(i + 1); }; bool Do() { int n; scanf("%d",&n); if(n == 0) return false; printf("%d\n",f[n]); return true; } int main() { while(Do()); return 0; }