题目描述
在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数.
例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图:
输入描述:
输入数据由多行组成,每行包含一个整数n,表示该测试实例的长方形方格的规格是2×n (1≤n≤90)。
输出描述:
对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。
输入例子:
1
3
2
输出例子:
1
3
2
乍一看,感觉有些复杂,想着用递推的思路,比如n = 2时
当n = 3时,
当n = 4时,可有n=2、n=3进行扩展
如果这样想,确实很复杂,因为存在很多的重复项,可能需要记住所有的状态进行比较。说明我们得思路不对。
经过上面的画图,我们知道f(2) = 2,f(3) = 3, f(4)=5,而n=4确实可有n=2、n=3进行扩展。从数字中可知f(4) = f(2) + f(3),那会不是斐波拉契尔数列呢?
其实你可以手动画一下f(5),确实会发现是斐波拉契尔数列问题。我们前面由n=2、n=3推n=4时,思路是正确的,但是我们进行扩展的时候进行排列(插入不同的位置)。其实n=3也是有n=1、n=2推出的,即本来n=1、n=2、n=3就存在内如的逻辑关系。
可能有部分道友会说我这是瞎猜的,没有直接证明f(n) = f(n - 1) + f(n - 2)(n ≥ 2)
,我也有点无奈,这个确实有点难证明。
在前一道爬楼梯的问题 PAT乙级(Basic Level)练习题 童年生活二三事,与此道题非常相似,横向摆放相当于跨2阶楼梯,纵向增加相当于跨1阶楼梯。
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
//建立一张表,用于记录f(n)各项值,注意数据溢出,使用long long型
long long fTable[91] = {0, 1, 2};
for (int i = 3; i < 91; ++i) {
fTable[i] = fTable[i - 1] + fTable[i - 2];
}
int number = 0;
//scanf返回值为正确输入数据的变量个数,当一个变量都没有成功获取数据时,此时返回-1
while (scanf("%d", &number) != - 1) {
printf("%lld\n", fTable[number]);
}
return 0;
}