算法(十):矩阵覆盖
作者:互联网
题目描述
我们可以用2 * 1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2 * 1的小矩形无重叠地覆盖一个2 * n的大矩形,总共有多少种方法?
题目分析
我们可以从小一点的n开始分析:
- 当n等于一时,此时小矩阵只能竖着放,只有一种方法。
- 当n等于二时,当第一个小矩阵竖着放时,右边还有2*1的矩阵,此时只有一种放法;当第一个小矩阵横着放时,右边没有矩阵,此时只有一种方法。所以总共有两种放法(1+1)。
- 当n等于三时,当第一个小矩阵竖着放时,右边还有2 * 2的矩阵,利用n等于二时的放法可以算出右边矩阵的放法,此时有两种放法。当第一个小矩阵横着放时,右边还有2*1的矩阵,根据n等于1时的方法可以算出右边矩阵的放法,此时只有一种放法。所以共有三种放法(2+1)。
- 当n等于四时,当第一个小矩阵竖着放时,右边还有2 * 3的矩阵,利用n等于三时的放法可以算出右边矩阵的法法,此时有三种放法。当第一个小矩阵横着放时,右边还有2 * 2的矩阵,利用n等于二时的放法可以算出右边矩阵的放法,此时有两种方法。所以共有五种f放法(3+2)。
- … …
由上面的分析易知从n=3开始,第n次的放法等于n-1次的放法数加上n-2次的放法数。非常类似斐波那契数列,所以我们可以使用递归,但是当n太大时会导致栈溢出。所以我们可以使用迭代的方法,使用两个指针储存第n-1次和第n-2次时的放法,避免内存的浪费。所以推荐使用迭代方法。
Java实现
- 递归实现
public int RectCover(int target) {
if(target <= 2){
return target;
}else{
return RectCover(target-1) + RectCover(target-2);
}
}
- 迭代实现
public int RectCover(int target) {
if(target <= 2){
return target;
}
int fn1 = 2;//指向n-1项
int fn2 = 1;//指向n-2项
//每次循环,两个指针同时后移
while(target-- > 2){
fn1 += fn2;
fn2 = fn1 - fn2;
}
return fn1;
}
标签:右边,覆盖,int,矩阵,放法,放时,算法,等于 来源: https://blog.csdn.net/qq_39240270/article/details/87195354